package com.adafruit.bluefruit.le.connect.ble; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothManager; import android.content.Context; import android.content.pm.PackageManager; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.nio.charset.Charset; import java.util.UUID; public class BleUtils { private final static String TAG = BleUtils.class.getSimpleName(); public static final int STATUS_BLE_ENABLED = 0; public static final int STATUS_BLUETOOTH_NOT_AVAILABLE = 1; public static final int STATUS_BLE_NOT_AVAILABLE = 2; public static final int STATUS_BLUETOOTH_DISABLED = 3; /* private static ResetBluetoothAdapter sResetHelper; */ // Use this check to determine whether BLE is supported on the device. Then you can selectively disable BLE-related features. public static int getBleStatus(Context context) { if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { return STATUS_BLE_NOT_AVAILABLE; } final BluetoothAdapter adapter = getBluetoothAdapter(context); // Checks if Bluetooth is supported on the device. if (adapter == null) { return STATUS_BLUETOOTH_NOT_AVAILABLE; } if (!adapter.isEnabled()) { return STATUS_BLUETOOTH_DISABLED; } return STATUS_BLE_ENABLED; } // Initializes a Bluetooth adapter. public static BluetoothAdapter getBluetoothAdapter(Context context) { final BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); if (bluetoothManager == null) { return null; } else { return bluetoothManager.getAdapter(); } } /* public static void enableWifi(boolean enable, Context context) { WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); wifiManager.setWifiEnabled(enable); } public static boolean isWifiEnabled(Context context) { WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); return wifiManager.isWifiEnabled(); } //region Reset Bluetooth Adapter public static void resetBluetoothAdapter(Context context, ResetBluetoothAdapterListener listener) { if (sResetHelper == null) { sResetHelper = new ResetBluetoothAdapter(context, listener); } else { Log.w(TAG, "Reset already in progress"); } } public static void cancelBluetoothAdapterReset(Context context) { if (isBluetoothAdapterResetInProgress()) { sResetHelper.cancel(context); sResetHelper = null; } } private static boolean isBluetoothAdapterResetInProgress() { return sResetHelper != null; } public interface ResetBluetoothAdapterListener { void resetBluetoothCompleted(); } private static class ResetBluetoothAdapter { // private Context mContext; private ResetBluetoothAdapterListener mListener; private final BroadcastReceiver mBleAdapterStateReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); onBleAdapterStatusChanged(state, context); } } }; ResetBluetoothAdapter(Context context, ResetBluetoothAdapterListener listener) { mListener = listener; // Set receiver IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); context.registerReceiver(mBleAdapterStateReceiver, filter); // Reset BluetoothAdapter bleAdapter = BleUtils.getBluetoothAdapter(context); if (bleAdapter != null && bleAdapter.isEnabled()) { boolean isDisablingBle = bleAdapter.disable(); if (isDisablingBle) { Log.w(TAG, "Reset ble adapter started. Waiting to turn off"); // Now wait for BluetoothAdapter.ACTION_STATE_CHANGED notification } else { Log.w(TAG, "Can't disable bluetooth adapter"); resetCompleted(context); } } } private void onBleAdapterStatusChanged(int state, Context context) { switch (state) { case BluetoothAdapter.STATE_OFF: { // Turn off has finished. Turn it on again Log.d(TAG, "Ble adapter turned off. Turning on"); BluetoothAdapter bleAdapter = BleUtils.getBluetoothAdapter(context); if (bleAdapter != null) { bleAdapter.enable(); } break; } case BluetoothAdapter.STATE_TURNING_OFF: break; case BluetoothAdapter.STATE_ON: { Log.d(TAG, "Ble adapter turned on. Reset completed"); // Turn on has finished. resetCompleted(context); break; } case BluetoothAdapter.STATE_TURNING_ON: break; } } private void resetCompleted(Context context) { context.unregisterReceiver(mBleAdapterStateReceiver); if (mListener != null) { mListener.resetBluetoothCompleted(); } sResetHelper = null; } public void cancel(Context context) { try { context.unregisterReceiver(mBleAdapterStateReceiver); } catch (IllegalArgumentException ignored) { } } } //endregion */ private final static char[] hexArray = "0123456789ABCDEF".toCharArray(); public static String bytesToHex(byte[] bytes) { if (bytes != null) { char[] hexChars = new char[bytes.length * 2]; for (int j = 0; j < bytes.length; j++) { int v = bytes[j] & 0xFF; hexChars[j * 2] = hexArray[v >>> 4]; hexChars[j * 2 + 1] = hexArray[v & 0x0F]; } return new String(hexChars); } else return null; } /* public static String byteToHex(byte value) { if (value > 0x0f) { char[] hexChars = new char[2]; hexChars[0] = hexArray[value >>> 4]; hexChars[1] = hexArray[value & 0x0F]; return new String(hexChars); } else { return "" + hexArray[value & 0x0F]; } }*/ // TODO: merge all these byteToXXX functions and remove unused ones public static String bytesToHex2(byte[] bytes) { StringBuilder stringBuffer = new StringBuilder(); for (byte aByte : bytes) { String charString = String.format("%02X", (byte) aByte); stringBuffer.append(charString).append(" "); } return stringBuffer.toString(); } public static @NonNull String bytesToText(byte[] bytes, boolean simplifyNewLine) { String text = new String(bytes, Charset.forName("UTF-8")); if (simplifyNewLine) { text = text.replaceAll("(\\r\\n|\\r)", "\n"); } return text; } /* public static String stringToHex(String string) { return bytesToHex(string.getBytes()); }*/ public static String bytesToHexWithSpaces(byte[] bytes) { StringBuilder newString = new StringBuilder(); for (byte aByte : bytes) { String byteHex = String.format("%02X", (byte) aByte); newString.append(byteHex).append(" "); } return newString.toString().trim(); } public static String getUuidStringFromByteArray(byte[] bytes) { StringBuilder buffer = new StringBuilder(); for (byte aByte : bytes) { buffer.append(String.format("%02x", aByte)); } return buffer.toString(); } /* public static UUID getUuidFromByteArrayBigEndian(byte[] bytes) { ByteBuffer bb = ByteBuffer.wrap(bytes); long high = bb.getLong(); long low = bb.getLong(); return new UUID(high, low); } public static UUID getUuidFromByteArraLittleEndian(byte[] bytes) { ByteBuffer bb = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN); long high = bb.getLong(); long low = bb.getLong(); return new UUID(low, high); } */ // region uuidToString public static String uuidToString(UUID uuid) { return uuidToString(uuid, true); } @SuppressWarnings("unused") static @Nullable String uuidToString(@Nullable UUID uuid, boolean shorten) { if (uuid == null) return null; String uppercaseUuidString = uuid.toString().toUpperCase(); if (shorten && uppercaseUuidString.startsWith("0000") && uppercaseUuidString.endsWith("-0000-1000-8000-00805F9B34FB")) { return uppercaseUuidString.substring(4, 8); } else { return uppercaseUuidString; } } // endregion }