简体   繁体   中英

Control Bluetooth from other fragments

Okay, so guys I need little bit help with Bluetooth. I am new at Java, so I need help with passing/controlling the same Bluetooth device from four different fragments. I read something about service, threads and objects or something like that, but I think there is easier and more understandable way to do it... My first Activity sends device address to MainControls and it successfully connects, but I dont know how to access it from another fragments.

Here is my main Fragment:

public class MainControls extends AppCompatActivity {

/**
 * The {@link android.support.v4.view.PagerAdapter} that will provide
 * fragments for each of the sections. We use a
 * {@link FragmentPagerAdapter} derivative, which will keep every
 * loaded fragment in memory. If this becomes too memory intensive, it
 * may be best to switch to a
 * {@link android.support.v4.app.FragmentStatePagerAdapter}.
 */
private SectionsPagerAdapter mSectionsPagerAdapter;
public String address;
String bckg;
TextView textView;

private ProgressDialog progress;
//BLE
public BluetoothAdapter myBluetooth = null;
public BluetoothSocket btSocket = null;
private boolean isBtConnected = false;

//SPP UUID
static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

/**
 * The {@link ViewPager} that will host the section contents.
 */
private ViewPager mViewPager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main_controls);
    textView = (TextView)findViewById(R.id.textView);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    Intent i = this.getIntent();
    address = i.getStringExtra("addr");
    bckg    = i.getStringExtra("bckg");
    mSectionsPagerAdapter = new 
    SectionsPagerAdapter(getSupportFragmentManager());

    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) findViewById(R.id.container);
    mViewPager.setAdapter(mSectionsPagerAdapter);

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(mViewPager);

    tabLayout.getTabAt(0).setIcon(R.drawable.led);
    tabLayout.getTabAt(1).setIcon(R.drawable.sliders);
    tabLayout.getTabAt(2).setIcon(R.drawable.controller);
    tabLayout.getTabAt(3).setIcon(R.drawable.wrench);
    new ConnectBT().execute();
}



public boolean onCreateOptionsMenu(Menu menu) {

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.my_options, menu);
    return true;
}

public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.about)
    {
        //return true;
    }

    if (id == R.id.info)
    {
        //return true;
    }

    if (id == R.id.nastavenia)
    {
        //return true;
    }

    return super.onOptionsItemSelected(item);
}

  /**
 * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
 * one of the sections/tabs/pages.
 */
 public class SectionsPagerAdapter extends FragmentPagerAdapter {

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                tab1Led tab1 = new tab1Led();
                return tab1;
            case 1:
                tab2Sliders tab2 = new tab2Sliders();
                return tab2;
            case 2:
                tab3Controller tab3 = new tab3Controller();
                return tab3;
            case 3:
                tab4Custom tab4 = new tab4Custom();
                return tab4;
            default:
                return null;
        }
    }

    @Override
    public int getCount() {
        // Show 3 total pages.
        return 4;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return "Led";
            case 1:
                return "Sliders";
            case 2:
                return "Controller";
            case 3:
                return "Custom";
        }
        return null;
    }
}

private void msg(String s){
    Toast.makeText(getApplicationContext(), s, Toast.LENGTH_SHORT).show();
}


/*Bluetooth class
 *
 *
 */
public class ConnectBT extends AsyncTask<Void, Void, Void>  // UI thread
{
    private boolean ConnectSuccess = true;
    @Override
    protected void onPreExecute()
    {
        progress = ProgressDialog.show(MainControls.this, "Connecting...", 
"Please wait!!!");  //show a progress dialog
    }
    @Override
    protected Void doInBackground(Void... devices) //while the progress 
dialog is shown, the connection is done in background
    {
        try
        {
            if (btSocket == null || !isBtConnected)
            {
                myBluetooth = BluetoothAdapter.getDefaultAdapter();
                BluetoothDevice btDevice = 
myBluetooth.getRemoteDevice(address);
                btSocket = 
btDevice.createInsecureRfcommSocketToServiceRecord(myUUID);
                BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
                btSocket.connect();
            }
        }
        catch (IOException e)
        {
            ConnectSuccess = false;
        }
        return null;
    }
    @Override
    protected void onPostExecute(Void result)
    {
        super.onPostExecute(result);

        if (!ConnectSuccess)
        {
            msg("Connection Failed. Try again.");
            Intent i = new Intent(MainControls.this, DeviceSearch.class);
            startActivity(i);
        }
        else {
            msg("Successfully Connected.");
            isBtConnected = true;

        }
        progress.dismiss();
    }
}
/*Bluetooth class
 *
 *
 */
}

My code is working, all my fragments work together and I got no Error. I connect successfully to device I want But the problem starts when I want to access it from another fragment...

Here is tab1Led, my first fragment:

public class tab1Led extends Fragment
{
public String address;
public int bckg;
TextView status, delayTextView;
int count, delay;
private SeekBar delaySeek;

public BluetoothAdapter myBluetooth;
public BluetoothSocket btSocket = null;

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState)
{
    final Context context = getActivity().getApplicationContext();
    //JJ


    View view = inflater.inflate(R.layout.led, container, false);
    TextView textView = (TextView)view.findViewById(R.id.textView);

    delayTextView = (TextView)view.findViewById(R.id.delayTextView);
    status                   = (TextView)view.findViewById(R.id.status);
    bckg = getActivity().getIntent().getExtras().getInt("bckg");
    address = getActivity().getIntent().getExtras().getString("addr");
    delaySeek = (SeekBar)view.findViewById(R.id.delaySeek);

    if(bckg == 0){
        textView.setText("Selected background: dark \n" + address);
    }
    else if(bckg == 1){
        textView.setText("Selected background: light \n" + address);
    }
    else{
        textView.setText("Error");
    }

    count = 0;
    delay = 250;
    delaySeek.setProgress(250);
    delayTextView.setText("Delay: " + String.valueOf(delay) + "ms");
    ImageButton imageButton = (ImageButton) 
    view.findViewById(R.id.imageButton);


    delaySeek.setOnSeekBarChangeListener(new 
    SeekBar.OnSeekBarChangeListener() {
        int progressChangedValue = 0;

        public void onProgressChanged(SeekBar seekBar, int progress, 
    boolean fromUser) {
            progressChangedValue = progress;
            delay = delaySeek.getProgress();
            delayTextView.setText("Delay: " + String.valueOf(delay) + 
    "ms");
        }

        public void onStartTrackingTouch(SeekBar seekBar) {
            delay = delaySeek.getProgress();
            delayTextView.setText("Delay: " + String.valueOf(delay) + 
    "ms");
        }

        public void onStopTrackingTouch(SeekBar seekBar) {
            delay = delaySeek.getProgress();
            delayTextView.setText("Delay: " + String.valueOf(delay) + 
    "ms");
        }
    });

    imageButton.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            if(count == 0){
                status.setText("LED is: OFF");
                count++;
            }
            else if(count == 1){
                status.setText("LED is: ON");
                count--;
            }

            else {
                count = 0;
            }
        }
    });



    return view;

}

private void msg(String s){
    Toast.makeText(getContext(), s, Toast.LENGTH_SHORT).show();
}

}

Okay so I have everything ready, I need to send char when the button is off and send char when the button is ON, but I just problems to access Bluetooth Device. Thanks for help :)

Your Bluetooth control defenitly should be in a Thread for more control.

Here is an example of how to implement a Blueetooth connection, the method called sendToTarget will be in charge of send data comming from the bluetooth to the UI activity or fragment.

public class MyBluetoothService {
private static final String TAG = "MY_APP_DEBUG_TAG";
private Handler mHandler; // handler that gets info from Bluetooth service

// Defines several constants used when transmitting messages between the
// service and the UI.
private interface MessageConstants {
    public static final int MESSAGE_READ = 0;
    public static final int MESSAGE_WRITE = 1;
    public static final int MESSAGE_TOAST = 2;

    // ... (Add other message types here as needed.)
}

private class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;
    private byte[] mmBuffer; // mmBuffer store for the stream

    public ConnectedThread(BluetoothSocket socket) {
        mmSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        // Get the input and output streams; using temp objects because
        // member streams are final.
        try {
            tmpIn = socket.getInputStream();
        } catch (IOException e) {
            Log.e(TAG, "Error occurred when creating input stream", e);
        }
        try {
            tmpOut = socket.getOutputStream();
        } catch (IOException e) {
            Log.e(TAG, "Error occurred when creating output stream", e);
        }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }

    public void run() {
        mmBuffer = new byte[1024];
        int numBytes; // bytes returned from read()

        // Keep listening to the InputStream until an exception occurs.
        while (true) {
            try {
                // Read from the InputStream.
                numBytes = mmInStream.read(mmBuffer);
                // Send the obtained bytes to the UI activity.
                Message readMsg = mHandler.obtainMessage(
                        MessageConstants.MESSAGE_READ, numBytes, -1,
                        mmBuffer);
                readMsg.sendToTarget();
            } catch (IOException e) {
                Log.d(TAG, "Input stream was disconnected", e);
                break;
            }
        }
    }

    // Call this from the main activity to send data to the remote device.
    public void write(byte[] bytes) {
        try {
            mmOutStream.write(bytes);

            // Share the sent message with the UI activity.
            Message writtenMsg = mHandler.obtainMessage(
                    MessageConstants.MESSAGE_WRITE, -1, -1, mmBuffer);
            writtenMsg.sendToTarget();
        } catch (IOException e) {
            Log.e(TAG, "Error occurred when sending data", e);

            // Send a failure message back to the activity.
            Message writeErrorMsg =
                    mHandler.obtainMessage(MessageConstants.MESSAGE_TOAST);
            Bundle bundle = new Bundle();
            bundle.putString("toast",
                    "Couldn't send data to the other device");
            writeErrorMsg.setData(bundle);
            mHandler.sendMessage(writeErrorMsg);
        }
    }

    // Call this method from the main activity to shut down the connection.
    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) {
            Log.e(TAG, "Could not close the connect socket", e);
        }
    }
}

}

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