我是android应用程序的新手。我正在尝试构建一个发现BLE模块连接到其GATT服务并显示数据的应用程序。我尝试显示的数据分为两部分。第一部分是包含经度和纬度的简单数据,而在底部,我使用一个片段根据数据中的坐标显示google地图。我包括一个操作栏菜单,以显示地图的法线和卫星视图。每当我尝试将mapview从法线改为卫星,反之亦然时,就会出现问题。每当我尝试执行gatt服务时,它就会自动断开连接。这不是崩溃。只是连接状态从已连接变为断开。 logcat中没有错误,我无法理解我在哪里犯错误。 我提供了代码的必要部分。如果您需要更多信息,请告诉我。
这是显示我的数据和地图的活动:
public final class ActivityData extends AppCompatActivity implements OnMapReadyCallback {
String myData, config, year, month, day, hour, min, sec, latitude, longitude, altitude, hAcc, fixType, xMotion, yMotion, zMotion, speed, signalStrength;
Double latDouble, longDouble;
GoogleMap mapview;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_data);
SupportMapFragment mapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
Toolbar actionbarMap = (Toolbar) findViewById(R.id.actionbar_map);
setSupportActionBar(actionbarMap);
myData = getIntent().getStringExtra(ControlActivity.DATA_HOLDER);
TextView timeView = (TextView) findViewById(R.id.time);
TextView dateView = (TextView) findViewById(R.id.date);
TextView latitudeView = (TextView) findViewById(R.id.latitude);
TextView longitudeView = (TextView) findViewById(R.id.longitude);
TextView altitudeView = (TextView) findViewById(R.id.altitude);
TextView hAccView = (TextView) findViewById(R.id.hAcc);
TextView signalStrengthView = (TextView) findViewById(R.id.signal_strength);
TextView fixTypeView = (TextView) findViewById(R.id.fix_type);
if (myData.contains(",")) {
StringTokenizer stringTokenizer = new StringTokenizer(myData, ",");
config = stringTokenizer.nextToken();
year = stringTokenizer.nextToken();
month = stringTokenizer.nextToken();
day = stringTokenizer.nextToken();
hour = stringTokenizer.nextToken();
min = stringTokenizer.nextToken();
sec = stringTokenizer.nextToken();
latitude = stringTokenizer.nextToken();
longitude = stringTokenizer.nextToken();
altitude = stringTokenizer.nextToken();
hAcc = stringTokenizer.nextToken();
fixType = stringTokenizer.nextToken();
xMotion = stringTokenizer.nextToken();
yMotion = stringTokenizer.nextToken();
zMotion = stringTokenizer.nextToken();
speed = stringTokenizer.nextToken();
signalStrength = stringTokenizer.nextToken();
latDouble = Double.parseDouble(latitude);
longDouble = Double.parseDouble(longitude);
timeView.setText("Time: " + hour + ":" + min + ":" + sec);
dateView.setText("Date: " + day + "/" + month + "/" + year);
latitudeView.setText("Lat: " + latitude);
longitudeView.setText("Long: " + longitude);
altitudeView.setText("Alt: " + altitude + "m");
hAccView.setText("Accuracy: " + hAcc + "mm");
signalStrengthView.setText("Signal Strength: " + signalStrength + "/5");
fixTypeView.setText("FixType: " + fixType);
} else {
timeView.setText(myData);
getSupportFragmentManager().beginTransaction().hide(mapFragment).commit();
latDouble = 0.00;
longDouble = 0.00;
}
}
@Override
public void onMapReady(GoogleMap googleMap){
LatLng location = new LatLng(latDouble,longDouble);
googleMap.addMarker(new MarkerOptions().position(location).title("You are here."));
googleMap.setMinZoomPreference(17.0f);
googleMap.setMaxZoomPreference(20.0f);
googleMap.setBuildingsEnabled(true);
googleMap.moveCamera(CameraUpdateFactory.newLatLng(location));
}
@Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.map__view_change, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId()){
case R.id.normalView:
mapview.setMapType(GoogleMap.MAP_TYPE_NORMAL);
invalidateOptionsMenu();
break;
case R.id.satelliteView:
mapview.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
invalidateOptionsMenu();
break;
}
return (super.onOptionsItemSelected(item));
}
}
这是它的xml文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_orange_light">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:textSize="20dp"
android:textStyle="bold"
android:paddingBottom="30dp"
android:paddingLeft="10dp"/>
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:textSize="20dp"
android:textStyle="bold"
android:paddingBottom="30dp"
android:paddingRight="10dp"/>
<TextView
android:id="@+id/latitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/time"
android:layout_alignLeft="@id/time"
android:textStyle="bold"
android:paddingLeft="10dp"/>
<TextView
android:id="@+id/longitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/latitude"
android:layout_alignLeft="@id/time"
android:textStyle="bold"
android:paddingLeft="10dp"/>
<TextView
android:id="@+id/altitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/longitude"
android:textStyle="bold"
android:layout_alignLeft="@id/time"
android:paddingLeft="10dp"/>
<TextView
android:id="@+id/hAcc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/date"
android:textStyle="bold"
android:layout_alignLeft="@id/date"
android:paddingRight="10dp"/>
<TextView
android:id="@+id/signal_strength"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/hAcc"
android:textStyle="bold"
android:layout_alignLeft="@id/date"
android:paddingRight="10dp"/>
<TextView
android:id="@+id/fix_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/signal_strength"
android:textStyle="bold"
android:layout_alignLeft="@id/date"
android:paddingRight="10dp"/>
</RelativeLayout>
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.example.v_daq_re.ActivityData">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="@+id/actionbar_map"
android:background="@android:color/holo_blue_bright"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
</androidx.appcompat.widget.Toolbar>
</fragment>
</LinearLayout>
这是我的控制活动:
public class ControlActivity extends AppCompatActivity {
private final static String TAG = ControlActivity.class.getSimpleName();
public static final String EXTRA_DEVICE_NAME = "DEVICE_NAME";
public static final String EXTRA_DEVICE_ADDRESS = "DEVICE_ADDRESS";
public static final String DATA_HOLDER = "DATA_HOLDER";
private String mDeviceName;
private String mDeviceAddress;
public String myData;
private boolean mConnected = false;
private BluetoothGattCharacteristic mNotifyCharacteristic;
private BluetoothLeService mBluetoothLeService;
TextView textViewState;
private ExpandableListView mGattServicesList;
private final String LIST_NAME = "NAME";
private final String LIST_UUID = "UUID";
private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mBluetoothLeService = ((BluetoothLeService.LocalBinder)service).getService();
if (!mBluetoothLeService.initialize()){
Log.e(TAG,"Unable to initialize Bluetooth");
finish();
}
//this part controls the auto gatt connection.
mBluetoothLeService.connect(mDeviceAddress);
}
@Override
public void onServiceDisconnected(ComponentName name) {
mBluetoothLeService = null;
}
};
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)){
mConnected = true;
updateConnectionState("CONNECTED");
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)){
mConnected = false;
updateConnectionState("DISCONNECTED");
clearUI();
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)){
displayGattServices(mBluetoothLeService.getSupportedGattServices());
} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)){
displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
}
}
};
private void clearUI(){
mGattServicesList.setAdapter((SimpleExpandableListAdapter)null);
}
private void updateConnectionState(final String st){
runOnUiThread(new Runnable() {
@Override
public void run() {
textViewState.setText("Status: " + st);
}
});
}
private void displayData(String data){
if (data != null){
new AlertDialog.Builder(ControlActivity.this)
.setTitle("Data Available")
.setNeutralButton("SHOW", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
final Intent intent = new Intent(ControlActivity.this, ActivityData.class);
intent.putExtra(DATA_HOLDER,data);
startActivity(intent);
}
})
.show( );
} else if (data == null){
new AlertDialog.Builder(ControlActivity.this)
.setTitle("No Data Available")
.setNeutralButton("DISSMISS", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.show( );
}
}
private void displayGattServices(List<BluetoothGattService>gattServices){
if (gattServices == null)
return;
String uuid = null;
String unknownServiceString = "Unknown Service";
String unknownCharaString = "Unknown Characteristic";
ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();
ArrayList<ArrayList<HashMap<String,String>>> gattCharacteristicData = new ArrayList<ArrayList<HashMap<String, String>>>();
mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
for (BluetoothGattService gattService : gattServices){
HashMap<String, String> currentServiceData = new HashMap<String, String>();
uuid = gattService.getUuid().toString();
currentServiceData.put(LIST_NAME, GattServices.lookup(uuid, unknownServiceString));
currentServiceData.put(LIST_UUID, uuid);
gattServiceData.add(currentServiceData);
ArrayList<HashMap<String, String>> gattCharacteristicGroupData = new ArrayList<HashMap<String, String>>();
List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
ArrayList<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>();
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics){
charas.add(gattCharacteristic);
HashMap<String, String> currentCharaData = new HashMap<String, String>();
uuid = gattCharacteristic.getUuid().toString();
currentCharaData.put(LIST_NAME, GattServices.lookup(uuid, unknownCharaString));
currentCharaData.put(LIST_UUID, uuid);
gattCharacteristicGroupData.add(currentCharaData);
}
mGattCharacteristics.add(charas);
gattCharacteristicData.add(gattCharacteristicGroupData);
}
SimpleExpandableListAdapter gattServiceAdapter = new SimpleExpandableListAdapter(
this,
gattServiceData,android.R.layout.simple_expandable_list_item_2,
new String[]{LIST_NAME,LIST_UUID},
new int[]{android.R.id.text1,
android.R.id.text2},
gattCharacteristicData,
android.R.layout.simple_expandable_list_item_2,
new String[]{LIST_NAME, LIST_UUID},
new int[]{android.R.id.text1,
android.R.id.text2}
);
mGattServicesList.setAdapter(gattServiceAdapter);
}
private final ExpandableListView.OnChildClickListener servicesListClickListner = new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
if (mGattCharacteristics != null){
final BluetoothGattCharacteristic characteristic = mGattCharacteristics.get(groupPosition).get(childPosition);
final int charaProp = characteristic.getProperties();
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0){
if (mNotifyCharacteristic != null){
mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, false);
mNotifyCharacteristic = null;
}
mBluetoothLeService.readCharacteristic(characteristic);
}
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0){
mNotifyCharacteristic = characteristic;
mBluetoothLeService.setCharacteristicNotification(characteristic, true);
}
return true;
}
return false;
}
};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_control);
final Intent intent = getIntent();
mDeviceName = intent.getStringExtra(EXTRA_DEVICE_NAME);
mDeviceAddress = intent.getStringExtra(EXTRA_DEVICE_ADDRESS);
TextView textViewDeviceName = (TextView)findViewById(R.id.textDeviceName);
TextView textViewDeviceAddr = (TextView)findViewById(R.id.textDeviceAddress);
textViewState = (TextView)findViewById(R.id.textState);
textViewDeviceName.setText("Name: " + mDeviceName);
textViewDeviceAddr.setText("Address: " + mDeviceAddress);
mGattServicesList = (ExpandableListView)findViewById(R.id.gatt_services_list);
mGattServicesList.setOnChildClickListener(servicesListClickListner);
Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
}
@Override
protected void onResume(){
super.onResume();
registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
if (mBluetoothLeService != null){
final boolean result = mBluetoothLeService.connect(mDeviceAddress);
Log.d(TAG, "Connect request result = " + result);
}
}
@Override
protected void onPause(){
super.onPause();
unregisterReceiver(mGattUpdateReceiver);
}
@Override
protected void onDestroy(){
super.onDestroy();
unbindService(mServiceConnection);
mBluetoothLeService = null;
}
private static IntentFilter makeGattUpdateIntentFilter(){
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
return intentFilter;
}
}
这是我的LE服务活动:
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
// super.onConnectionStateChange(gatt, status, newState);
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED){
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.i(TAG,"Connected to GATT server.");
Log.i(TAG,"Attempting to start service discovery:" + mBluetoothGatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED){
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG,"Disconnected from GATT server.");
broadcastUpdate(intentAction);
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status){
if (status == BluetoothGatt.GATT_SUCCESS){
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
} else{
Log.w(TAG,"onServicesDiscovered received: " + status);
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status){
if (status == BluetoothGatt.GATT_SUCCESS){
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic){
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
};
private void broadcastUpdate(final String action) {
final Intent intent = new Intent(action);
sendBroadcast(intent);
}
private void broadcastUpdate(final String action,
final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);
//this part defines how data is shown. i am modifying it to show only String version of data.
final byte[] data = characteristic.getValue();
if (data != null && data.length > 0) {
intent.putExtra(EXTRA_DATA, new String(data));
}
sendBroadcast(intent);
}
public class LocalBinder extends Binder{
BluetoothLeService getService(){
return BluetoothLeService.this;
}
}
@Override
public IBinder onBind(Intent intent){
return mBinder;
}
@Override
public boolean onUnbind(Intent intent){
close();
return super.onUnbind(intent);
}
private final IBinder mBinder = new LocalBinder();
public boolean initialize(){
if (mBluetoothManager == null){
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager == null){
Log.e(TAG,"Unable to initialize BluetoothManager.");
return false;
}
}
mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter == null){
Log.e(TAG,"Unable to obtain a BluetoothAdapter.");
return false;
}
return true;
}
public boolean connect(final String address){
if (mBluetoothAdapter == null || address == null){
Log.w(TAG,"BluetoothAdapter not initialized or unspecified address.");
return false;
}
if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress) && mBluetoothGatt != null){
Log.d(TAG,"Trying to use an existing mBluetoothGatt for connection.");
if (mBluetoothGatt.connect()){
mConnectionState = STATE_CONNECTING;
return true;
} else {
return false;
}
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null){
Log.w(TAG,"Device not found. Unable to connect.");
return false;
}
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
Log.d(TAG, "Trying to create a new connection.");
mBluetoothDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
return true;
}
public void disconnect(){
if (mBluetoothAdapter == null || mBluetoothGatt == null){
Log.w(TAG,"BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.disconnect();
}
public void close(){
if (mBluetoothGatt == null){
return;
}
mBluetoothGatt.close();
mBluetoothGatt = null;
}
public void readCharacteristic(BluetoothGattCharacteristic characteristic){
if (mBluetoothAdapter == null || mBluetoothGatt == null){
Log.w(TAG,"BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.readCharacteristic(characteristic);
}
public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled){
if (mBluetoothAdapter == null || mBluetoothGatt == null){
Log.w(TAG,"BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
//TODO: descriptor update here. use only if necessary.
if(GattServices.V_DAQ_GATT_SERVICE.equals(characteristic.getUuid())){
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(GattServices.V_DAQ_GATT_CHARACTERISTIC));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
}
}
public List<BluetoothGattService> getSupportedGattServices(){
if (mBluetoothGatt == null)
return null;
return mBluetoothGatt.getServices();
}
这是我的logcat:
2019-10-14 17:14:26.258 3426-3426/? E/Zygote: isWhitelistProcess - Process is Whitelisted
2019-10-14 17:14:26.259 3426-3426/? E/Zygote: accessInfo : 1
2019-10-14 17:14:26.278 3426-3426/? I/xample.v_daq_r: Late-enabling -Xcheck:jni
2019-10-14 17:14:26.784 3426-3476/com.example.v_daq_re I/Adreno: QUALCOMM build : 0a66665, If34e3488e3
Build Date : 04/05/19
OpenGL ES Shader Compiler Version: EV031.25.16.00
Local Branch :
Remote Branch : refs/tags/AU_LINUX_ANDROID_LA.UM.7.1.C1.09.00.00.526.029
Remote Branch : NONE
Reconstruct Branch : NOTHING
2019-10-14 17:14:26.806 3426-3447/com.example.v_daq_re D/BluetoothGatt: discoverServices() - device: D4:CA:6E:F0:B7:ED
2019-10-14 17:14:26.807 3426-3444/com.example.v_daq_re D/InputTransport: Input channel constructed: fd=71
2019-10-14 17:14:26.808 3426-3447/com.example.v_daq_re I/BluetoothLeService: Attempting to start service discovery:true
2019-10-14 17:14:26.810 3426-3447/com.example.v_daq_re D/BluetoothGatt: onSearchComplete() = Device=D4:CA:6E:F0:B7:ED Status=0
2019-10-14 17:14:26.819 3426-3426/com.example.v_daq_re D/InputMethodManager: prepareNavigationBarInfo() DecorView@d4eb87d[ControlActivity]
2019-10-14 17:14:26.820 3426-3426/com.example.v_daq_re D/InputMethodManager: getNavigationBarColor() -855310
2019-10-14 17:14:26.820 3426-3426/com.example.v_daq_re D/InputMethodManager: startInputInner - Id : 0
2019-10-14 17:14:26.869 3426-3426/com.example.v_daq_re D/AbsListView: in onLayout changed
2019-10-14 17:14:26.873 3426-3426/com.example.v_daq_re D/ViewRootImpl@a846a88[ControlActivity]: MSG_RESIZED: frame=Rect(0, 0 - 1440, 3040) ci=Rect(0, 144 - 0, 192) vi=Rect(0, 144 - 0, 192) or=1
2019-10-14 17:14:27.236 3426-3482/com.example.v_daq_re D/BluetoothGatt: onClientConnectionState() - status=22 clientIf=4 device=D4:CA:6E:F0:B7:ED
2019-10-14 17:14:27.240 3426-3482/com.example.v_daq_re I/BluetoothLeService: Disconnected from GATT server.
2019-10-14 17:14:27.253 3426-3426/com.example.v_daq_re D/AbsListView: in onLayout changed
我省略了主要活动和Gatt服务定义活动,因为它们仅处理ble扫描和gatt服务列表。 如果可能的话,请在我的代码中指出错误,并具体说明,因为我对此很陌生并且缺乏适当的理解。先感谢您。