简体   繁体   中英

How to transfer data via Bluetooth from two different activities?

I tried to send data from my app to my Arduino board to make the led light. The problem is that if I send from my main activity it works but if I send it from a second activity ( HolopickerColor ), it doesn't work and I don't get any errors. Thanks for your anwsers.

MainActivity :

public class MainActivity extends AppCompatActivity{
private Button mPairedBtn;
Button on, find;
public BluetoothAdapter BA;
private ProgressDialog mProgressDlg;
// public ConnectedThread mConnectedThread;
private ArrayList<BluetoothDevice> mDeviceList = new ArrayList<BluetoothDevice>();
private DrawerLayout mDrawerLayout;

private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
Button btnOn, btnOff;
// SPP UUID service
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

// MAC-address of Bluetooth module (you must edit this line)
private static String address ;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    on = (Button) findViewById(R.id.btn_enable);

    find = (Button) findViewById(R.id.btn_scan);
    mPairedBtn = (Button) findViewById(R.id.btn_view_paired);


    BA = BluetoothAdapter.getDefaultAdapter();
    mProgressDlg = new ProgressDialog(this);


    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    ActionBar actionBar = getSupportActionBar();
    actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
    actionBar.setDisplayHomeAsUpEnabled(true);

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

    NavigationView navigationView = (NavigationView) findViewById(R.id.navigation_view);
    navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(MenuItem menuItem) {
            menuItem.setChecked(true);
            mDrawerLayout.closeDrawers();
            Toast.makeText(MainActivity.this, menuItem.getTitle(), Toast.LENGTH_LONG).show();
            switch (menuItem.getItemId()) {
                case R.id.nav_item_colorlight:
                    Intent color = new Intent(MainActivity.this, HolopickerColor.class);
                   // color.putExtra("color", ConnectedThread.getInstance());
                    startActivity(color);
                    break;
                case R.id.nav_item_effectlight:
                    Intent light = new Intent(MainActivity.this, LightEffect.class);
                    startActivity(light);
                    break;
                case R.id.nav_item_music:
                    Intent music = new Intent(MainActivity.this, Music.class);
                    startActivity(music);
                    break;
                case R.id.nav_item_about:
                    Intent about = new Intent(MainActivity.this, About.class);
                    startActivity(about);
                    break;
            }

            return true;
        }
    });

    mProgressDlg.setMessage("Scanning...");
    mProgressDlg.setCancelable(false);
    mProgressDlg.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();

            BA.cancelDiscovery();
        }
    });

    if (BA == null) {
        showUnsupported();
    } else {
        mPairedBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Set<BluetoothDevice> pairedDevices = BA.getBondedDevices();

                if (pairedDevices == null || pairedDevices.size() == 0) {
                    showToast("No Paired Devices Found");
                } else {
                    ArrayList<BluetoothDevice> list = new ArrayList<BluetoothDevice>();

                    list.addAll(pairedDevices);

                    Intent intent = new Intent(MainActivity.this, DeviceListActivity.class);

                    intent.putParcelableArrayListExtra("device.list", list);

                    startActivity(intent);
                }
            }
        });

        find.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                BA.startDiscovery();
            }
        });

        on.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (BA.isEnabled()) {
                    BA.disable();

                    showDisabled();
                    try
                    {
                        btSocket.close();
                    } catch (IOException e2)
                    {
                        //insert code to deal with this
                    }

                } else {
                    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

                    startActivityForResult(intent, 1000);
                }
            }
        });

        if (BA.isEnabled()) {
            showEnabled();
        } else {
            showDisabled();
        }
    }
    IntentFilter filter = new IntentFilter();

    filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
    filter.addAction(BluetoothDevice.ACTION_FOUND);
    filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
    filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);



    registerReceiver(mReceiver, filter);

    btnOn = (Button) findViewById(R.id.btnOn);
    btnOff = (Button) findViewById(R.id.btnOff);


    // Set up onClick listeners for buttons to send 1 or 0 to turn on/off LED
    btnOff.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
           /* r = 255;
            g = 15;
            b = 50;


            mConnectedThread.write("r"+Integer.toString(r)+"\n");    // Send "0" via Bluetooth
            mConnectedThread.write("g"+Integer.toString(g)+"\n");
            mConnectedThread.write("b"+Integer.toString(b)+"\n");*/
            ConnectedThread.getInstance().write("1");
            Toast.makeText(getBaseContext(), "Turn off LED", Toast.LENGTH_SHORT).show();
        }
    });

    btnOn.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            //cathode nen 1 la off, o la on
            ConnectedThread.getInstance().write("0");    // Send "1" via Bluetooth //gui nhan ne
            Toast.makeText(getBaseContext(), "Turn on LED", Toast.LENGTH_SHORT).show();
        }
    });

    //Get MAC address from DeviceListActivity via intent
    //   Intent intent = getIntent();

    //Get the MAC address from the DeviceListActivty via EXTRA
    //address = intent.getStringExtra(DeviceListActivity.EXTRA_DEVICE_ADDRESS);

    // MAC-address of Bluetooth module (you must edit this line)
    address = "30:14:10:09:07:86";

    //create device and set the MAC address
    BluetoothDevice device = BA.getRemoteDevice(address);

    try {
        btSocket = createBluetoothSocket(device);
    } catch (IOException e) {
        Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_LONG).show();
    }
    // Establish the Bluetooth socket connection.
    try
    {
        btSocket.connect();
    } catch (IOException e) {
        try
        {
            btSocket.close();
        } catch (IOException e2)
        {
            //insert code to deal with this
        }
    }

    ConnectedThread.createInstance(btSocket);
    ConnectedThread.getInstance().start();
    //I send a character when resuming.beginning transmission to check device is connected
    //If it is not an exception will be thrown in the write method and finish() will be called

}



private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {

    return  device.createRfcommSocketToServiceRecord(MY_UUID);
    //creates secure outgoing connecetion with BT device using UUID
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    switch (id) {
        case android.R.id.home:
            mDrawerLayout.openDrawer(GravityCompat.START);
            return true;
    }

    return super.onOptionsItemSelected(item);
}

public void onPause() {
    if (BA != null) {
        if (BA.isDiscovering()) {
            BA.cancelDiscovery();
        }
    }

    try
    {
        //Don't leave Bluetooth sockets open when leaving activity
        btSocket.close();
    } catch (IOException e2) {
        //insert code to deal with this
    }
    super.onPause();

}

@Override
public void onDestroy() {
    unregisterReceiver(mReceiver);

    super.onDestroy();
}

private void showEnabled() {
    Toast.makeText(getApplicationContext(), "on", Toast.LENGTH_LONG).show();
    on.setText("Disable");
    on.setEnabled(true);

    mPairedBtn.setEnabled(true);
    find.setEnabled(true);
}

private void showDisabled() {
    Toast.makeText(getApplicationContext(), "off", Toast.LENGTH_LONG).show();
    on.setText("Enable");
    on.setEnabled(true);

    mPairedBtn.setEnabled(false);
    find.setEnabled(false);
}

private void showUnsupported() {
    Toast.makeText(getApplicationContext(), "Bluetooth is unsupported by this device", Toast.LENGTH_LONG).show();

    on.setText("Enable");
    on.setEnabled(false);

    mPairedBtn.setEnabled(false);
    find.setEnabled(false);
}

private void showToast(String message) {
    Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
            final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);

            if (state == BluetoothAdapter.STATE_ON) {
                showToast("Enabled");

                showEnabled();
            }
        } else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
            mDeviceList = new ArrayList<BluetoothDevice>();

            mProgressDlg.show();
        } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
            mProgressDlg.dismiss();

            Intent newIntent = new Intent(MainActivity.this, DeviceListActivity.class);

            newIntent.putParcelableArrayListExtra("device.list", mDeviceList);

            startActivity(newIntent);
        } else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

            mDeviceList.add(device);

            showToast("Found device " + device.getName());
        }
    }
};

Second activity :

public class HolopickerColor extends AppCompatActivity implements ColorPicker.OnColorChangedListener {
private TextView text;
com.larswerkman.holocolorpicker.ColorPicker picker;
SVBar svBar ;
Button test;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_holopicker_color);
    picker = (ColorPicker) findViewById(R.id.picker);
    svBar = (SVBar) findViewById(R.id.svbar);

    text = (TextView) findViewById(R.id.color1);

    picker.addSVBar(svBar);

    picker.getColor();

    picker.setOnColorChangedListener(this);

    picker.setShowOldCenterColor(false);// Tat mau cu
    test = (Button)findViewById(R.id.test);
    test.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            ConnectedThread.getInstance().write("r255\n");
            Toast.makeText(getBaseContext(),"yes",Toast.LENGTH_LONG).show();
        }
    });
    //ConnectedThread.getInstance().start();
}


public void onColorChanged(int color) {
    // TODO Auto-generated method stub
    text.setTextColor(color);//hien mau len chu
    if (ConnectedThread.getInstance() != null) {
        int r = (color >> 16) & 0xFF;//xuat kieu mau ra thanh chu
        int g = (color >> 8) & 0xFF;
        int b = (color >> 0) & 0xFF;

        // mTcpClient.sendMessage(Integer.toHexString(picker.getColor()));

        ConnectedThread.getInstance().write("r255");//gui ko nhan ne

Here is the ConnectedThread :

class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final OutputStream mmOutStream; // cai nay e can implement Serializable nua
    private static ConnectedThread instance = null;

    private ConnectedThread(BluetoothSocket socket) {
        mmSocket = socket;
        OutputStream tmpOut = null;

        // Get the input and output streams, using temp objects because
        // member streams are final
        try {
            tmpOut = socket.getOutputStream();
        } catch (IOException e) { }

        mmOutStream = tmpOut;
    }

    public static void createInstance(BluetoothSocket socket) {
        if (instance == null) {
            instance = new ConnectedThread(socket);
        }
    }

    public static ConnectedThread getInstance() {
        return instance;
    }

    //write method
    public void write(String input) {
        byte[] msgBuffer = input.getBytes();           //converts entered String into bytes
        try {
            mmOutStream.write(msgBuffer);                //write bytes over BT connection via outstream
        } catch (IOException e) {
            cancel();

        }
    }

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

The problem is that you are creating your ConnectedThread singleton instance using a BluetoothSocket , and then you close that same socket in the onPause method of your activity. So basically, after onPause has been called, the ConnectedThread instance cannot send anything anymore. Instead of this you should have ConnectedThread manage the socket, ie keep a reference to it and then close it when you no longer need it or have detected a problem.

By the way, each time you call write on ConnectedThread after the socket is closed, your cancel method is called. You would have been able to easily detect the problem if you were not silencing exceptions in this method. This is why you should never have an empty catch block.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM