简体   繁体   English

制作带有播放控件的蓝牙扬声器连接到手机

[英]Making a Bluetooth speaker with playback controls connected to phone

I am recently working on a project.我最近在做一个项目。 The idea is to make a Bluetooth speaker which has playback controls like pause,play, next song on the speaker itself.这个想法是制作一个蓝牙扬声器,它在扬声器本身具有播放控制,如暂停、播放、下一首歌曲。 The speaker is to be connected to the mobile phone via Bluetooth.扬声器将通过蓝牙连接到手机。 Ultimately i wanted to achieve the button control(on speaker) of songs I play on mobile which is connected to speaker via Bluetooth.最终我想实现我在通过蓝牙连接到扬声器的手机上播放的歌曲的按钮控制(在扬声器上)。

I was able to make the speaker connected via Bluetooth to the phone and could play songs but the biggest challenge is i couldn't pause or forward the playlist on phone from speaker side.我能够通过蓝牙将扬声器连接到手机并播放歌曲,但最大的挑战是我无法从扬声器端暂停或转发手机上的播放列表。 What i understood is that the speaker is able to receive signals from phone to play songs but how do i send a command(like next song via physical button) from the speaker to the phone(via a micro controller like arduino).我的理解是扬声器能够接收来自手机的信号来播放歌曲,但我如何从扬声器向手机发送命令(如通过物理按钮的下一首歌曲)(通过像 arduino 这样的微型 controller)。 I hope I stated my situation well.我希望我能很好地说明我的情况。 I came across idea like having multiple bluetooth pairing, custom programming of the BT module that i'll be using, etc.我遇到了一些想法,比如有多个蓝牙配对、我将使用的 BT 模块的自定义编程等。

I am open to all kinds of way this can be done and I really appreciate if anyone could recommend me the proper BT modules and micro-controller to be used.我对所有可以做到这一点的方式持开放态度,如果有人能向我推荐合适的 BT 模块和微控制器,我将不胜感激。

About the BT module, I suggest you to use an HC-05.关于BT模块,我建议你使用HC-05。 For the MCU, Arduino cannot be used to play music... so you should optain for Rasberry, but I am not sure.对于 MCU,Arduino 不能用于播放音乐......所以你应该选择 Rasberry,但我不确定。 Also I never used it...还有我没用过...

If you need some code similar, I mede an app for a greenhouse which displays temperature, humidity and light inside it.如果你需要一些类似的代码,我为温室设计了一个应用程序,它可以显示温室内的温度、湿度和光线。

If you wanna read these class in order: gitHub .如果您想按顺序阅读这些 class: gitHub But I have to post the code, too: maybe I could delete the repo a day但我也必须发布代码:也许我可以每天删除回购

BLTSocket class: BLT插座 class:

public class BLTSocket extends Service {

private static final UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static boolean isBtConnected = false;
private static BluetoothAdapter adapter = null;
private static BluetoothSocket socket = null;
private static InputStream is = null;
private static OutputStream os = null;

public BLTSocket(){

}

/**
 * Constructor called when a bluetooth device has been clicked in the layout
 * If the phone's bluetooth socket has not already connected , it tries to initialize
 * the new connection with the one clicked.
 * Get the stream and set @isBtConnected as true
 *
 * @param address - MAC address of the bluetooth device
 */
public BLTSocket(String address){
    if (!isBtConnected || !socket.isConnected()) {
        try {
            adapter = BluetoothAdapter.getDefaultAdapter();
            BluetoothDevice device = adapter.getRemoteDevice(address);
            socket = device.createInsecureRfcommSocketToServiceRecord(uuid);
            socket.connect();
            is = socket.getInputStream();
            os = socket.getOutputStream();
            isBtConnected = true;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

@Override
public void onCreate() {
    HandlerThread handlerThread = new HandlerThread("SURVEYS_SERVICE", Process.THREAD_PRIORITY_BACKGROUND);
    handlerThread.start();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    survey();
    return START_STICKY;
}

/**
 * This handler keeps updating the three surveys reading their current value
 * from the bluetooth module's input stream.
 * Set the the circular progress bar and the own text view below as the relative value
 */
Handler handler = new Handler();
Runnable runnable;
private void survey() {

    runnable = new Runnable() {
        @RequiresApi(api = Build.VERSION_CODES.O)
        @Override
        public void run() {
            byte[] survey = new byte[12];
            try {
                /*
                    Once got the current values of the three surveys,
                    it sets the relative progress bar and the text view
                 */
                if(is.read(survey) > 0){
                    for(int i = 0; i < 3; i++){
                        MainActivity.getProgressBars()[i].setProgress(survey[i]);
                        MainActivity.getTextViews()[i].setText(String.valueOf(survey[i]) + (i == 0 ? "°C" : '%'));
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
            handler.postDelayed(this, 2000);
        }
    };
    runnable.run();

}

/**
 * Called when the user click on the UPDATE SEED button
 * on the popup menu of the ViewSeed layout
 *
 * Send to the HC-05 the new recommended values
 *
 * @param values
 */
public void updateSeed(int[] values){
    try {
        handler.removeCallbacks(runnable);
        for(int value : values) {
            os.write(value);
        }
        os.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }finally {
        handler.postDelayed(runnable, 2000);
    }
}


@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

/**
 * Close the socket and set @isBtConnected as false when the app is closed or crashes
 */
@Override
public void onDestroy() {
    try {
        this.socket.close();
        this.isBtConnected = false;
    }catch (IOException e) {
        e.printStackTrace();
    }
}

} }

BLTActivity: BLT活动:

public class BluetoothActivity extends AppCompatActivity {

ActivityBluetoothBinding activityBluetoothBinding;

private BluetoothAdapter adapter;
private Set<BluetoothDevice> pairedDevices;
private ListView listBLTDevice;
private TextView bltTV;

private BluetoothDevice deviceSelected;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    activityBluetoothBinding = DataBindingUtil.setContentView(this, R.layout.activity_bluetooth);
    activityBluetoothBinding.setSettings(MainActivity.loadSettings);
    this.bltTV = findViewById(R.id.bltTV);
    this.listBLTDevice = findViewById(R.id.listBLTDevices);
    setBlt();
}

public static BLTSocket bltSocket;

private void setBlt(){
    this.adapter = BluetoothAdapter.getDefaultAdapter();
    //If the adapter is null, the user's phone hasn't a bluetooth radio
    if(adapter != null){
        if(!adapter.isEnabled()){
            //If the bluetooth is disabled, it asks to the user to enable it
            startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE), 1);
        }

        //The bonded devices are those ones which have already been compared
        pairedDevices = adapter.getBondedDevices();
        this.bltTV.setText(pairedDevices.size() + " Devices Found");

        if(pairedDevices.size() > 0){

            /*
             *  Create a new list of strings which every one contains the name of one compared
             *  bluetooth radio. The array list is given to the adapter.
             */
            final ArrayList<String> arrayList = new ArrayList<>();
            for (BluetoothDevice device : pairedDevices){
                arrayList.add(device.getName());
            }
            final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, getListViewLayout(), arrayList);
            this.listBLTDevice.setAdapter(adapter);

            /*
                When an item (string that represents a bluetooth radio) has been clicked,
                its MAC address is given to the BLTSocket constructor, which will set
                the opportune variable, objects and connects our radio with the selected one
             */
            this.listBLTDevice.setOnItemClickListener( (parent, v, pos, id) -> {
                deviceSelected = (BluetoothDevice) pairedDevices.toArray()[pos];
                Toast.makeText(getApplicationContext(), "Device Selected: " + deviceSelected.getName() + "\n" + deviceSelected.getAddress(), Toast.LENGTH_SHORT).show();
                bltSocket = new BLTSocket(deviceSelected.getAddress());
                startService(new Intent(this, BLTSocket.class));
            } );
        }
    }else{
        Toast.makeText(getApplicationContext(), "Seems like your device hasn't any bluetooth adapter...", Toast.LENGTH_SHORT).show();
    }
}

/**
 * Called when setting the ArrayAdapter to chose list layout with the right color of the text
 * If the user has the dark mode enabled, this method returns the white list and vice versa
 *
 * @return the id of the opportune listview layout
 */
private int getListViewLayout() {
    return !MainActivity.loadSettings.isDarkMode() ? R.layout.listview_blacktext_layout : R.layout.listview_whitetext_layout;
}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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