Implementation of Bluetooth Attendance Function Based on ibeacon in Android

  • 2021-10-24 23:39:20
  • OfStack

Description:

ibeacon devices actively transmit Bluetooth signals, When the mobile phone turns on Bluetooth and approaches the ibeacon device, it will receive the Bluetooth signal sent by the device. At this time, it is only necessary to confirm which ibeacon device is according to the four values of uuid, major, minor and mac of the ibeacon device, and then call the server attendance interface (ibeacon device only to confirm that the mobile phone is beside the attendance machine and does not need to send attendance data to ibeacon device), which can realize Bluetooth attendance.

1. Add static permissions (in the AndroidManifest. xml file, requires Bluetooth and location permissions)


<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />

2. Detect and turn on Bluetooth and GPS

1. Whether Bluetooth is supported:


 if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
      ToastUtils.show(" Bluetooth is not supported on this machine ,  Unable to punch in Bluetooth ");
      ((Activity) context).finish();
      return false;
    }
    final BluetoothManager bm = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
      mBleAdapter = bm.getAdapter(); //mBleAdapter Is a global variable, is a BluetoothAdapter Object 
    }
    if (bleAdapter == null) {
      ToastUtils.show(" This machine does not support low power Bluetooth function ,  Unable to punch in Bluetooth ");
      ((Activity) context).finish();
      return false;
    }
    return true;

2. Whether to turn on GPS:


LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
boolean gps = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
boolean network = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (gps || network) {
   return true;
}
return false;

3. Turn on GPS:


Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivityForResult(intent, ActivityCode.ACTIVITY_CODE_GPS);

4. Turn on Bluetooth:


Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
((Activity) mContext).startActivityForResult(enableBtIntent, ActivityCode.ACTIVITY_CODE_OPEN_BLE);

3. Apply for Bluetooth permissions dynamically


private boolean check(Context context, String permission) {
    return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
 
  }
 
  /**
   *  Authority application 
   */
  private void searchBle(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
      if (!check(mContext, Manifest.permission.ACCESS_FINE_LOCATION) || !check(mContext, Manifest.permission.ACCESS_COARSE_LOCATION)) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, ACCESS_LOCATION);
      } else {
        // Perform a Bluetooth search 
      }
    } else {
      // Perform a Bluetooth search 
    }
  }
 
  @Override
  public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
      case ACCESS_LOCATION:
        if (hasAllPermissionsGranted(grantResults)) {
          // Perform a Bluetooth search 
        } else {
          ToastUtils.show(" Please open permissions ");
        }
        break;
    }
  }

4. Search for Bluetooth


 /**
 *  Search Bluetooth 
*/
  public void searchBle() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
      mBleAdapter.startLeScan(mLeScanCallback);
    }
  }
 
  /**
   *  Search results callback 
   */
  private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
 
    @Override
    public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
      //fromScanData Method sets the ibeacon Data is converted into entity objects, which include uuid , major , minor , mac , distance Such information 
      final BleUtil.DeviceInfo info = BleUtil.fromScanData(device, rssi, scanRecord);
      if (info == null || TextUtils.isEmpty(info.uuid) || info.major <= 0 || info.minor <= 0 || TextUtils.isEmpty(info.mac)) {
        return;
      }
      if (mUuids == null || mUuids.isEmpty()) {
        // Turn off Bluetooth search here 
        mBleAdapter.stopLeScan(mLeScanCallback);
        return;
      }
      for (MachineInfo machineInfo : mUuids) {
        if (info.uuid.equalsIgnoreCase(machineInfo.uuid) &&
            (!TextUtils.isEmpty(machineInfo.major) && info.major == Integer.parseInt(machineInfo.major)) &&
            (!TextUtils.isEmpty(machineInfo.minor) && info.minor == Integer.parseInt(machineInfo.minor)) &&
            info.mac.equalsIgnoreCase(machineInfo.mac) && info.distance <= MAX_DISTANCE) {
          mConnected = true;
          // The callback notifies the outside, and the interface updates the available attendance status 
          if (mListener != null) {
            mListener.onConnected();
          }
          // This is a delayed call stopLeScan Turn off Bluetooth search 
          beginTimer();
          break;
        }
      }
    }
  };

Step 5 Attendance

This step uses the API provided by the server to add attendance records


Related articles: