process_name_ptr:13505 com.example.ibasket 2024-05-02 18:21:55.557 13505-13505 zygote64 com.example.ibasket E 无法解析/product/etc/mfz.xml:Tinyxml2错误(3):Error = XML_ERROR_FILE_NOT_FOUND ErrorID = 3(0x3)行号= 0:文件名=/product/etc/mfz.xml 2024-05-02 18:21:55.557 13505-13505 zygote64 com.example.ibasket E MemoryFreeze XMLFile 未找到
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.IBASKET"
tools:targetApi="31">
<activity
android:name=".MainActivity4"
android:exported="false" />
<activity
android:name=".MainActivity3"
android:exported="false" />
<activity
android:name=".MainActivity2"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity2.java
package com.example.ibasket;
import android.Manifest;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import java.util.Set;
import java.util.UUID;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.schedulers.Schedulers;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
public class MainActivity2 extends AppCompatActivity {
Button btnBluetooth, searchDevices;
ImageView imageView;
TextView btReadings, btDevices;
//Global variables we will use in the
private static final String TAG = "FrugalLogs";
private static final int REQUEST_ENABLE_BT = 1;
//We will use a Handler to get the BT Connection statys
public static Handler handler;
private final static int ERROR_READ = 0; // used in bluetooth handler to identify message update
BluetoothDevice arduinoBTModule = null;
UUID arduinoUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //We declare a default UUID to create the global variable
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
//Intances of BT Manager and BT Adapter needed to work with BT in Android.
BluetoothManager bluetoothManager = getSystemService(BluetoothManager.class);
BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
btnBluetooth = findViewById(R.id.btnBluetooth);
imageView = findViewById(R.id.imageView2);
btReadings = findViewById(R.id.btReadings);
searchDevices = findViewById(R.id.searchDevices);
btDevices = findViewById(R.id.btDevices);
Log.d(TAG, "Begin Execution");
//Using a handler to update the interface in case of an error connecting to the BT device
//My idea is to show handler vs RxAndroid
handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case ERROR_READ:
String arduinoMsg = msg.obj.toString(); // Read message from Arduino
btReadings.setText(arduinoMsg);
break;
}
}
};
// Create an Observable from RxAndroid
//The code will be executed when an Observer subscribes to the the Observable
final Observable<String> connectToBTObservable = Observable.create(emitter -> {
Log.d(TAG, "Calling connectThread class");
//Call the constructor of the ConnectThread class
//Passing the Arguments: an Object that represents the BT device,
// the UUID and then the handler to update the UI
ConnectThread connectThread = new ConnectThread(arduinoBTModule, arduinoUUID, handler);
connectThread.run();
//Check if Socket connected
if (connectThread.getMmSocket().isConnected()) {
Log.d(TAG, "Calling ConnectedThread class");
//The pass the Open socket as arguments to call the constructor of ConnectedThread
ConnectedThread connectedThread = new ConnectedThread(connectThread.getMmSocket());
connectedThread.run();
if(connectedThread.getValueRead()!=null)
{
// If we have read a value from the Arduino
// we call the onNext() function
//This value will be observed by the observer
emitter.onNext(connectedThread.getValueRead());
}
//We just want to stream 1 value, so we close the BT stream
connectedThread.cancel();
}
// SystemClock.sleep(5000); // simulate delay
//Then we close the socket connection
connectThread.cancel();
//We could Override the onComplete function
emitter.onComplete();
});
btnBluetooth.setOnClickListener(new View.OnClickListener() {
@SuppressLint("CheckResult")
@Override
public void onClick(View v) {
btReadings.setText("");
if (arduinoBTModule != null) {
//We subscribe to the observable until the onComplete() is called
//We also define control the thread management with
// subscribeOn: the thread in which you want to execute the action
// observeOn: the thread in which you want to get the response
connectToBTObservable.
observeOn(AndroidSchedulers.mainThread()).
subscribeOn(Schedulers.io()).
subscribe(valueRead -> {
//valueRead returned by the onNext() from the Observable
btReadings.setText(valueRead);
//We just scratched the surface with RxAndroid
});
}
}
});
searchDevices.setOnClickListener(new View.OnClickListener() {
//Display all the linked BT Devices
@Override
public void onClick(View view) {
//Check if the phone supports BT
if (bluetoothAdapter == null) {
// Device doesn't support Bluetooth
Log.d(TAG, "Device doesn't support Bluetooth");
} else {
Log.d(TAG, "Device support Bluetooth");
//Check BT enabled. If disabled, we ask the user to enable BT
if (!bluetoothAdapter.isEnabled()) {
Log.d(TAG, "Bluetooth is disabled");
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
Log.d(TAG, "We don't BT Permissions");
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
Log.d(TAG, "Bluetooth is enabled now");
} else {
Log.d(TAG, "We have BT Permissions");
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
Log.d(TAG, "Bluetooth is enabled now");
}
} else {
Log.d(TAG, "Bluetooth is enabled");
}
String btDevicesString="";
Set < BluetoothDevice > pairedDevices = bluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
// There are paired devices. Get the name and address of each paired device.
for (BluetoothDevice device: pairedDevices) {
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
Log.d(TAG, "deviceName:" + deviceName);
Log.d(TAG, "deviceHardwareAddress:" + deviceHardwareAddress);
//We append all devices to a String that we will display in the UI
btDevicesString=btDevicesString+deviceName+" || "+deviceHardwareAddress+"\n";
//If we find the HC 05 device (the Arduino BT module)
//We assign the device value to the Global variable BluetoothDevice
//We enable the button "Connect to HC 05 device"
if (deviceName.equals("HC-05")) {
Log.d(TAG, "HC-05 found");
arduinoUUID = device.getUuids()[0].getUuid();
arduinoBTModule = device;
//HC -05 Found, enabling the button to read results
btnBluetooth.setEnabled(true);
}
btDevices.setText(btDevicesString);
}
}
}
Log.d(TAG, "Button Pressed");
}
});
// Initialize views
ImageView loltImageView = findViewById(R.id.imageView2);
// Set click listener for the lolt image
loltImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Navigate to MainActivity3
startActivity(new Intent(MainActivity2.this, MainActivity3.class));
}
});
}
}
ConnectThread.java
package com.example.ibasket;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.util.Log;
import java.io.IOException;
import java.util.UUID;
//Class that will open the BT Socket to the Arduino BT Module
//Given a BT device, the UUID and a Handler to set the results
public class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private static final String TAG = "FrugalLogs";
public static Handler handler;
private final static int ERROR_READ = 0;
@SuppressLint("MissingPermission")
public ConnectThread(BluetoothDevice device, UUID MY_UUID, Handler handler) {
// Use a temporary object that is later assigned to mmSocket
// because mmSocket is final.
BluetoothSocket tmp = null;
this.handler=handler;
try {
// Get a BluetoothSocket to connect with the given BluetoothDevice.
// MY_UUID is the app's UUID string, also used in the server code.
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.e(TAG, "Socket's create() method failed", e);
}
mmSocket = tmp;
}
@SuppressLint("MissingPermission")
public void run() {
try {
// Connect to the remote device through the socket. This call blocks
// until it succeeds or throws an exception.
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and return.
handler.obtainMessage(ERROR_READ, "Unable to connect to the BT device").sendToTarget();
Log.e(TAG, "connectException: " + connectException);
try {
mmSocket.close();
} catch (IOException closeException) {
Log.e(TAG, "Could not close the client socket", closeException);
}
return;
}
// The connection attempt succeeded. Perform work associated with
// the connection in a separate thread.
//manageMyConnectedSocket(mmSocket);
}
// Closes the client socket and causes the thread to finish.
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close the client socket", e);
}
}
public BluetoothSocket getMmSocket(){
return mmSocket;
}
}
ConnectedThread.java
package com.example.ibasket;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
//Class that given an open BT Socket will
//Open, manage and close the data Stream from the Arduino BT device
public class ConnectedThread extends Thread {
private static final String TAG = "FrugalLogs";
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private String valueRead;
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);
}
//Input and Output streams members of the class
//We wont use the Output stream of this project
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public String getValueRead(){
return valueRead;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes = 0; // bytes returned from read()
int numberOfReadings = 0; //to control the number of readings from the Arduino
// Keep listening to the InputStream until an exception occurs.
//We just want to get 1 temperature readings from the Arduino
while (numberOfReadings < 1) {
try {
buffer[bytes] = (byte) mmInStream.read();
String readMessage;
// If I detect a "\n" means I already read a full measurement
if (buffer[bytes] == '\n') {
readMessage = new String(buffer, 0, bytes);
Log.e(TAG, readMessage);
//Value to be read by the Observer streamed by the Obervable
valueRead=readMessage;
bytes = 0;
numberOfReadings++;
} else {
bytes++;
}
} catch (IOException e) {
Log.d(TAG, "Input stream was disconnected", e);
break;
}
}
}
// 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);
}
}
}
activity_main2.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg2"
tools:context=".MainActivity2">
<Button
android:id="@+id/btnBluetooth"
android:layout_width="232dp"
android:layout_height="48dp"
android:backgroundTint="#AB760A"
android:text="BLUETOOTH"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.653" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="104dp"
android:layout_height="80dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.894"
app:srcCompat="@drawable/ylwq" />
<TextView
android:id="@+id/btReadings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.306"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.857" />
<Button
android:id="@+id/searchDevices"
android:layout_width="215dp"
android:layout_height="53dp"
android:text="Search linked BT devices"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.426"
tools:ignore="MissingConstraints" />
<TextView
android:id="@+id/btDevices"
android:layout_width="200dp"
android:layout_height="60dp"
android:text=""
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.523" />
</androidx.constraintlayout.widget.ConstraintLayout>
build.gradle(模块:应用程序)
dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.11.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
implementation 'androidx.multidex:multidex:2.0.1'
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'io.reactivex.rxjava3:rxjava:3.1.2'
}
我想在这个应用程序上添加蓝牙功能。运行应用程序后,蓝牙功能无法使用。 logcat错误显示如下
我总是收到消息“无法连接到 BT 设备”,并且它没有显示通过 Arduino 获得的值。您知道为什么我收到此错误(搜索设备正常工作并且连接按钮已激活)吗?