From 61e348865a8f8c3286c50a3cfa973952f5c8fb6e Mon Sep 17 00:00:00 2001 From: Munchax10 <79412545+Munchax10@users.noreply.github.com> Date: Fri, 21 Jun 2024 22:35:04 +0300 Subject: [PATCH] Add bluetooth scanning Feel free to make changes! --- app/src/main/AndroidManifest.xml | 2 + .../com/termux/api/TermuxApiReceiver.java | 6 + .../com/termux/api/apis/BluetoothScanAPI.java | 122 ++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 app/src/main/java/com/termux/api/apis/BluetoothScanAPI.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8411d0003..481ef7823 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,6 +11,8 @@ + + diff --git a/app/src/main/java/com/termux/api/TermuxApiReceiver.java b/app/src/main/java/com/termux/api/TermuxApiReceiver.java index 6efaafe16..4d14653fd 100644 --- a/app/src/main/java/com/termux/api/TermuxApiReceiver.java +++ b/app/src/main/java/com/termux/api/TermuxApiReceiver.java @@ -10,6 +10,7 @@ import com.termux.api.apis.AudioAPI; import com.termux.api.apis.BatteryStatusAPI; +import com.termux.api.apis.BluetoothScanAPI; import com.termux.api.apis.BrightnessAPI; import com.termux.api.apis.CallLogAPI; import com.termux.api.apis.CameraInfoAPI; @@ -90,6 +91,11 @@ private void doWork(Context context, Intent intent) { case "BatteryStatus": BatteryStatusAPI.onReceive(this, context, intent); break; + case "BluetoothScan": + if (TermuxApiPermissionActivity.checkAndRequestPermissions(context, intent, Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.BLUETOOTH, Manifest.permission.ACCESS_FINE_LOCATION)) { + BluetoothScanAPI.onReceive(context, intent); + } + break; case "Brightness": if (!Settings.System.canWrite(context)) { TermuxApiPermissionActivity.checkAndRequestPermissions(context, intent, Manifest.permission.WRITE_SETTINGS); diff --git a/app/src/main/java/com/termux/api/apis/BluetoothScanAPI.java b/app/src/main/java/com/termux/api/apis/BluetoothScanAPI.java new file mode 100644 index 000000000..aa3da67c8 --- /dev/null +++ b/app/src/main/java/com/termux/api/apis/BluetoothScanAPI.java @@ -0,0 +1,122 @@ +package com.termux.api.apis; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.util.JsonWriter; + +import com.termux.api.util.ResultReturner; +import com.termux.shared.logger.Logger; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Objects; + +public class BluetoothScanAPI { + + private static final ArrayList devices = new ArrayList<>(); + private static final String LOG_TAG = "BluetoothScanAPI"; + private static BluetoothAdapter adapter; + private static boolean scanning = false; + + private static final BroadcastReceiver receiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (Objects.equals(intent.getAction(), BluetoothDevice.ACTION_FOUND)) { + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + if (device != null) { + devices.add(device); + } + } + } + }; + + public static void onReceive(final Context context, final Intent intent) { + Logger.logDebug(LOG_TAG, "onReceive"); + + ResultReturner.returnData(context, intent, new ResultReturner.ResultJsonWriter() { + @Override + public void writeJson(JsonWriter out) throws Exception { + String mode = intent.getStringExtra("mode"); + if (mode == null) return; + out.beginObject(); + switch (mode.toLowerCase()) { + case "start": + if (start(context)) { + out.name("error").value(false); + } else { + out.name("error").value(true); + out.name("reason").value("Already running!"); + } + break; + case "stop": + if (stop(context)) { + out.name("error").value(false); + printList(out, true); + } else { + out.name("error").value(true); + out.name("reason").value("Already stopped!"); + } + break; + case "info": + if (scanning) { + out.name("error").value(false); + printList(out, false); + } else { + out.name("error").value(true); + out.name("reason").value("Scan is not running!"); + } + break; + default: + out.name("error").value(true); + out.name("reason").value("Invalid option! Choose one from [start, stop, info]"); + break; + } + out.endObject(); + } + }); + + + } + + private static void printList(JsonWriter out, boolean clear) { + try { + out.name("devices"); + out.beginArray(); + for (BluetoothDevice device : devices) { + out.beginObject(); + out.name("name").value(device.getName()); + out.name("address").value(device.getAddress()); + out.endObject(); + } + out.endArray(); + if (clear) { + devices.clear(); + } + } catch (IOException ex) { + Logger.logError(Arrays.toString(ex.getStackTrace())); + } + } + + private static boolean start(Context context) { + if (scanning) return false; + context.getApplicationContext().registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_FOUND)); + adapter = BluetoothAdapter.getDefaultAdapter(); + adapter.startDiscovery(); + scanning = true; + return true; + } + + private static boolean stop(Context context) { + if (!scanning) return false; + adapter.cancelDiscovery(); + context.getApplicationContext().unregisterReceiver(receiver); + scanning = false; + return true; + } + +}