关于BT模块,我建议你使用HC-05。对于 MCU,Arduino 不能用来播放音乐……所以你应该选择 Rasberry,但我不确定。还有我没用过...
如果你需要一些类似的代码,我为温室设计了一个应用程序,它可以显示温室内的温度、湿度和光线。
如果您想按顺序阅读这些课程:gitHub。但我也必须发布代码:也许我可以每天删除回购
BLTSocket 类:
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();
}
}
}
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;
}
}