在Android Studio中的活动之间传递蓝牙连接

时间:2016-10-28 15:07:54

标签: android bluetooth connection

我在这里找到了一个与Arduino进行蓝牙连接的非常简单的例子。 http://www.instructables.com/id/Android-Bluetooth-Control-LED-Part-2/ 下载完整项目: http://www.instructables.com/id/Android-Bluetooth-Control-LED-Part-2/step9/Download/ 非常感谢作者Deyson! 它有两个Acitvities:     1)DeviceList.java     这显示了配对的设备,您可以选择所需的设备:

package com.led.led;
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Set;


public class DeviceList extends ActionBarActivity
{
//widgets
Button btnPaired;
ListView devicelist;
//Bluetooth
private BluetoothAdapter myBluetooth = null;
private Set<BluetoothDevice> pairedDevices;
public static String EXTRA_ADDRESS = "device_address";

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_device_list);

    //Calling widgets
    btnPaired = (Button)findViewById(R.id.button);
    devicelist = (ListView)findViewById(R.id.listView);

    //if the device has bluetooth
    myBluetooth = BluetoothAdapter.getDefaultAdapter();

    if(myBluetooth == null)
    {
        //Show a mensag. that the device has no bluetooth adapter
        Toast.makeText(getApplicationContext(), "Bluetooth Device Not Available", Toast.LENGTH_LONG).show();

        //finish apk
        finish();
    }
    else if(!myBluetooth.isEnabled())
    {
            //Ask to the user turn the bluetooth on
            Intent turnBTon = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(turnBTon,1);
    }

    btnPaired.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v)
        {
            pairedDevicesList();
        }
    });

}

private void pairedDevicesList()
{
    pairedDevices = myBluetooth.getBondedDevices();
    ArrayList list = new ArrayList();

    if (pairedDevices.size()>0)
    {
        for(BluetoothDevice bt : pairedDevices)
        {
            list.add(bt.getName() + "\n" + bt.getAddress()); //Get the device's name and the address
        }
    }
    else
    {
        Toast.makeText(getApplicationContext(), "No Paired Bluetooth Devices Found.", Toast.LENGTH_LONG).show();
    }

    final ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1, list);
    devicelist.setAdapter(adapter);
    devicelist.setOnItemClickListener(myListClickListener); //Method called when the device from the list is clicked

}

private AdapterView.OnItemClickListener myListClickListener = new AdapterView.OnItemClickListener()
{
    public void onItemClick (AdapterView<?> av, View v, int arg2, long arg3)
    {
        // Get the device MAC address, the last 17 chars in the View
        String info = ((TextView) v).getText().toString();
        String address = info.substring(info.length() - 17);

        // Make an intent to start next activity.
        Intent i = new Intent(DeviceList.this, ledControl.class);

        //Change the activity.
        i.putExtra(EXTRA_ADDRESS, address); //this will be received at ledControl (class) Activity
        startActivity(i);
    }
};


@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_device_list, menu);
    return true;
}

@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();

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

    return super.onOptionsItemSelected(item);
   }
}

2)ledControl.java这是按钮和通讯:

package com.led.led;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.os.AsyncTask;

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


public class ledControl extends ActionBarActivity {

Button btnOn, btnOff, btnDis;
SeekBar brightness;
TextView lumn;
String address = null;
private ProgressDialog progress;
BluetoothAdapter myBluetooth = null;
BluetoothSocket btSocket = null;
private boolean isBtConnected = false;
//SPP UUID. Look for it
static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

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

    Intent newint = getIntent();
    address = newint.getStringExtra(DeviceList.EXTRA_ADDRESS); //receive the address of the bluetooth device

    //view of the ledControl
    setContentView(R.layout.activity_led_control);

    //call the widgtes
    btnOn = (Button)findViewById(R.id.button2);
    btnOff = (Button)findViewById(R.id.button3);
    btnDis = (Button)findViewById(R.id.button4);
    brightness = (SeekBar)findViewById(R.id.seekBar);
    lumn = (TextView)findViewById(R.id.lumn);

    new ConnectBT().execute(); //Call the class to connect

    //commands to be sent to bluetooth
    btnOn.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            turnOnLed();      //method to turn on
        }
    });

    btnOff.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v)
        {
            turnOffLed();   //method to turn off
        }
    });

    btnDis.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            Disconnect(); //close connection
        }
    });

    brightness.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            if (fromUser==true)
            {
                lumn.setText(String.valueOf(progress));
                try
                {
                    btSocket.getOutputStream().write(String.valueOf(progress).getBytes());
                }
                catch (IOException e)
                {

                }
            }
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    });
}

private void Disconnect()
{
    if (btSocket!=null) //If the btSocket is busy
    {
        try
        {
            btSocket.close(); //close connection
        }
        catch (IOException e)
        { msg("Error");}
    }
    finish(); //return to the first layout

}

private void turnOffLed()
{
    if (btSocket!=null)
    {
        try
        {
            btSocket.getOutputStream().write("TF".toString().getBytes());
        }
        catch (IOException e)
        {
            msg("Error");
        }
    }
}

private void turnOnLed()
{
    if (btSocket!=null)
    {
        try
        {
            btSocket.getOutputStream().write("TO".toString().getBytes());
        }
        catch (IOException e)
        {
            msg("Error");
        }
    }
}

// fast way to call Toast
private void msg(String s)
{
    Toast.makeText(getApplicationContext(),s,Toast.LENGTH_LONG).show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_led_control, menu);
    return true;
}

@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();

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

    return super.onOptionsItemSelected(item);
}

private class ConnectBT extends AsyncTask<Void, Void, Void>  // UI thread
{
    private boolean ConnectSuccess = true; //if it's here, it's almost connected

    @Override
    protected void onPreExecute()
    {
        progress = ProgressDialog.show(ledControl.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();//get the mobile bluetooth device
             BluetoothDevice dispositivo = myBluetooth.getRemoteDevice(address);//connects to the device's address and checks if it's available
             btSocket = dispositivo.createInsecureRfcommSocketToServiceRecord(myUUID);//create a RFCOMM (SPP) connection
             BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
             btSocket.connect();//start connection
            }
        }
        catch (IOException e)
        {
            ConnectSuccess = false;//if the try failed, you can check the exception here
        }
        return null;
    }
    @Override
    protected void onPostExecute(Void result) //after the doInBackground, it checks if everything went fine
    {
        super.onPostExecute(result);

        if (!ConnectSuccess)
        {
            msg("Connection Failed. Is it a SPP Bluetooth? Try again.");
            finish();
        }
        else
        {
            msg("Connected.");
            isBtConnected = true;
        }
        progress.dismiss();
    }
  }
}

所以我在ledControl.java中添加了一个按钮来打开第三页,称为编程:

btnProgram.setOnClickListener(new View.OnClickListener()  //Open programing page
{
   @Override
   public void onClick(View v)
   {                
     Intent i = new Intent(getApplicationContext(), Programing.class);
     startActivity(i);
   }
});

问题是第三页没有&#34;记住&#34;在蓝牙连接上,所以我无法发送任何信息。我知道一些帖子也在同一个主题中。我尝试了很多选择,但没有成功。 如果有人可以提出一个简单的代码来保持活动之间的BT连接,那对像我这样的初学者来说将是非常有益的, 那么怎样才能以简单的方式通过BT连接? 我亲你问你,请在上面的代码中提出你的建议。 感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您可以实现自定义Application子类,并在那里存储蓝牙连接。然后,一个活动可以从那里请求它,因为它可以用于应用程序的生命周期。

public class MyApplication extends Application
{

    private static MyApplication sInstance;

    public static MyApplication getApplication() {
        return sInstance;
    }

    BluetoothSocket btSocket = null;

    public void onCreate() {
        super.onCreate();

        sInstance = this;
    }

    public void setupBluetoothConnection()
    {
        // Either setup your connection here, or pass it in
    }

    public BluetoothSocket getCurrentBluetoothConnection()
    {
        return btSocket;
    }
}

在你的活动电话中:

MyApplication.getInstance().setupBluetoothConnection();

后来:

MyApplication.getInstance().getCurrentBluetoothConnection();

您需要指定您的应用在AndroidManifest.xml中使用此Application类

<application android:icon="@drawable/icon" android:label="@string/app_name"
    android:name="com.yourpackage.MyApplication">

另一种选择是实现设置/存储蓝牙连接的自定义服务,但这将是更多的开销和维护。

答案 1 :(得分:1)

只是一个想法,为什么不保留所有蓝牙的东西&amp;在没有绑定到Activity生命周期的单独Service类中进行通信?

您可以通过活页夹/意图或EventBus与服务进行通信,并将其与UI分离。

作为此解决方案的奖励,您将仅在一个地方实施所有通信(发送和接收),而不是将其用于多个活动。