Update Bluetooth logger files

This commit is contained in:
2026-08-18 18:52:29 -06:00
parent eb16dbaeac
commit ffac2efd22
585 changed files with 4505 additions and 422 deletions
@@ -59,7 +59,7 @@ public class BluetoothTrackingService extends Service implements LocationListene
}
if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
BluetoothAdapter.ERROR);
BluetoothAdapter.ERROR);
if (state == BluetoothAdapter.STATE_OFF ||
state == BluetoothAdapter.STATE_TURNING_OFF)
disconnectAll("Manual / Intentional Disconnect");
@@ -95,7 +95,7 @@ public class BluetoothTrackingService extends Service implements LocationListene
(before.lastRssiAt <= 0 || now - before.lastRssiAt > 180000L);
db.telemetry(address, broadcastName, null, Integer.valueOf(rssi), now, null);
db.recordObservation(address, now, rssi, broadcastName, db.lookupOui(address),
null, null, -1, -1, null, fix);
null, null, -1, -1, null, fix);
if (firstFreshSight) { captureFresh(address, now); configureLocation(); }
}
} else if ("android.bluetooth.device.action.BATTERY_LEVEL_CHANGED".equals(action)) {
@@ -105,12 +105,12 @@ public class BluetoothTrackingService extends Service implements LocationListene
db.telemetry(address, broadcastName, Integer.valueOf(battery), null, now, fix);
} else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
BluetoothDevice.ERROR);
BluetoothDevice.ERROR);
if (state == BluetoothDevice.BOND_BONDED)
db.markTracked(address, broadcastName);
else if (state == BluetoothDevice.BOND_NONE)
db.disconnected(address, broadcastName, now, fix,
"Manual / Intentional Disconnect");
"Manual / Intentional Disconnect");
}
resolveVendor(address, -1);
notifyChanged();
@@ -118,25 +118,25 @@ public class BluetoothTrackingService extends Service implements LocationListene
};
private final BluetoothAdapter.LeScanCallback leScanCallback =
new BluetoothAdapter.LeScanCallback() {
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
if (device == null) return;
String address = address(device);
if (address == null) return;
long now = System.currentTimeMillis();
DeviceRecord before = db.get(address);
boolean firstFreshSight = before != null && before.trackBroadcast == 1 &&
(before.lastRssiAt <= 0 || now - before.lastRssiAt > 180000L);
db.telemetry(address, name(device), null, Integer.valueOf(rssi), now, null);
if (firstFreshSight) { captureFresh(address, now); configureLocation(); }
int companyId = parseCompanyId(scanRecord);
resolveVendor(address, companyId);
String vendor = companyId >= 0 ? db.lookupCompany(companyId) : db.lookupOui(address);
db.recordObservation(address, now, rssi, name(device), vendor, null, null,
-1, companyId, bytesToHex(scanRecord), currentFix());
notifyChanged();
}
};
new BluetoothAdapter.LeScanCallback() {
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
if (device == null) return;
String address = address(device);
if (address == null) return;
long now = System.currentTimeMillis();
DeviceRecord before = db.get(address);
boolean firstFreshSight = before != null && before.trackBroadcast == 1 &&
(before.lastRssiAt <= 0 || now - before.lastRssiAt > 180000L);
db.telemetry(address, name(device), null, Integer.valueOf(rssi), now, null);
if (firstFreshSight) { captureFresh(address, now); configureLocation(); }
int companyId = parseCompanyId(scanRecord);
resolveVendor(address, companyId);
String vendor = companyId >= 0 ? db.lookupCompany(companyId) : db.lookupOui(address);
db.recordObservation(address, now, rssi, name(device), vendor, null, null,
-1, companyId, bytesToHex(scanRecord), currentFix());
notifyChanged();
}
};
private final Runnable scanTask = new Runnable() {
public void run() {
@@ -146,12 +146,12 @@ public class BluetoothTrackingService extends Service implements LocationListene
if (!bluetooth.isDiscovering()) bluetooth.startDiscovery();
bluetooth.startLeScan(leScanCallback);
handler.postDelayed(new Runnable() {
public void run() {
try { bluetooth.stopLeScan(leScanCallback); }
catch (Exception ignored) { }
configureLocation();
}
}, 12000L);
public void run() {
try { bluetooth.stopLeScan(leScanCallback); }
catch (Exception ignored) { }
configureLocation();
}
}, 12000L);
}
} catch (Exception ignored) { }
handler.postDelayed(this, 90000L);
@@ -204,8 +204,8 @@ public class BluetoothTrackingService extends Service implements LocationListene
if (!hasLocationPermission()) return;
try {
lastLocation = newer(locationManager.getLastKnownLocation(
LocationManager.GPS_PROVIDER), locationManager.getLastKnownLocation(
LocationManager.NETWORK_PROVIDER));
LocationManager.GPS_PROVIDER), locationManager.getLastKnownLocation(
LocationManager.NETWORK_PROVIDER));
} catch (Exception ignored) { }
}
@@ -218,9 +218,9 @@ public class BluetoothTrackingService extends Service implements LocationListene
if (phoneBattery < 20) interval *= 4L;
try {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
interval, 10f, this);
interval, 10f, this);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
interval, 10f, this);
interval, 10f, this);
} catch (Exception ignored) { }
}
@@ -260,10 +260,10 @@ public class BluetoothTrackingService extends Service implements LocationListene
locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, once, null);
locationManager.requestSingleUpdate(LocationManager.NETWORK_PROVIDER, once, null);
handler.postDelayed(new Runnable() {
public void run() {
try { locationManager.removeUpdates(once); } catch (Exception ignored) { }
}
}, 15000L);
public void run() {
try { locationManager.removeUpdates(once); } catch (Exception ignored) { }
}
}, 15000L);
} catch (Exception ignored) { }
}
@@ -297,7 +297,7 @@ public class BluetoothTrackingService extends Service implements LocationListene
private TrackerDatabase.Fix fix(Location location) {
return new TrackerDatabase.Fix(location.getLatitude(), location.getLongitude(),
location.hasAccuracy() ? location.getAccuracy() : 0);
location.hasAccuracy() ? location.getAccuracy() : 0);
}
private void resolveVendor(String address, int companyId) {
String vendor = companyId >= 0 ? db.lookupCompany(companyId) : null;
@@ -390,9 +390,9 @@ public class BluetoothTrackingService extends Service implements LocationListene
private boolean hasLocationPermission() {
return getPackageManager().checkPermission("android.permission.ACCESS_FINE_LOCATION",
getPackageName()) == PackageManager.PERMISSION_GRANTED ||
getPackageName()) == PackageManager.PERMISSION_GRANTED ||
getPackageManager().checkPermission("android.permission.ACCESS_COARSE_LOCATION",
getPackageName()) == PackageManager.PERMISSION_GRANTED;
getPackageName()) == PackageManager.PERMISSION_GRANTED;
}
private boolean hasBluetoothPermission() {
@@ -421,7 +421,7 @@ public class BluetoothTrackingService extends Service implements LocationListene
private void showDisconnectAlert(DeviceRecord record, String reason) {
Intent open = new Intent(this, MainActivity.class);
PendingIntent pending = PendingIntent.getActivity(this, record.address.hashCode(), open,
PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(record.displayName() + " disconnected")
@@ -446,7 +446,7 @@ public class BluetoothTrackingService extends Service implements LocationListene
private Notification buildNotification() {
Intent open = new Intent(this, MainActivity.class);
PendingIntent pending = PendingIntent.getActivity(this, 0, open,
PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_launcher).setContentTitle("Bluetooth Item Finder")
.setContentText("Watching your tracked items").setOngoing(true)
@@ -455,8 +455,8 @@ public class BluetoothTrackingService extends Service implements LocationListene
try {
Class<?> channelClass = Class.forName("android.app.NotificationChannel");
Object channel = channelClass.getConstructor(String.class,
CharSequence.class, Integer.TYPE).newInstance(CHANNEL_ID,
"Item tracking", 2);
CharSequence.class, Integer.TYPE).newInstance(CHANNEL_ID,
"Item tracking", 2);
NotificationManager manager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
NotificationManager.class.getMethod("createNotificationChannel", channelClass)
@@ -468,3 +468,4 @@ public class BluetoothTrackingService extends Service implements LocationListene
return builder.build();
}
}
@@ -1,30 +1,16 @@
package com.wytehat.btlogger;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.net.Uri;
import android.provider.Settings;
import android.provider.MediaStore;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import android.app.*;
import android.content.*;
import android.content.pm.*;
import android.graphics.*;
import android.net.*;
import android.os.*;
import android.provider.*;
import android.view.*;
import android.widget.*;
import java.io.*;
import java.lang.reflect.*;
public class MainActivity extends Activity implements ItemActionListener {
private static final int PERMISSIONS = 100;
@@ -53,16 +39,16 @@ public class MainActivity extends Activity implements ItemActionListener {
adapter = new DeviceListAdapter(this, db.tracked(), this);
list.setAdapter(adapter);
findViewById(R.id.devices_button).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { startActivity(new Intent(MainActivity.this,
DeviceManagerActivity.class)); }
});
public void onClick(View v) { startActivity(new Intent(MainActivity.this,
DeviceManagerActivity.class)); }
});
findViewById(R.id.map_all_button).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { startActivity(new Intent(MainActivity.this,
MapActivity.class)); }
});
public void onClick(View v) { startActivity(new Intent(MainActivity.this,
MapActivity.class)); }
});
findViewById(R.id.settings_button).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { showSettings(); }
});
public void onClick(View v) { showSettings(); }
});
requestNeededPermissions();
startTracker();
}
@@ -126,9 +112,9 @@ public class MainActivity extends Activity implements ItemActionListener {
boolean enabled = record.trackBroadcast != 1;
db.setTrackBroadcast(record.address, enabled);
sendBroadcast(new Intent(BluetoothTrackingService.ACTION_CONFIG_CHANGED)
.setPackage(getPackageName()));
.setPackage(getPackageName()));
Toast.makeText(this, enabled ? "Will log GPS while this item is broadcasting" :
"Broadcast location tracking disabled", Toast.LENGTH_LONG).show();
"Broadcast location tracking disabled", Toast.LENGTH_LONG).show();
reload();
}
@@ -183,7 +169,7 @@ public class MainActivity extends Activity implements ItemActionListener {
.setPositiveButton("SAVE", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
db.updateProfile(record.address, input.getText().toString(),
record.photoUri, record.iconPreset);
record.photoUri, record.iconPreset);
reload();
}
}).setNegativeButton("CANCEL", null).show();
@@ -198,7 +184,7 @@ public class MainActivity extends Activity implements ItemActionListener {
public void onClick(DialogInterface dialog, final int selected) {
db.updateTracking(record.address, minutes[selected], record.pinColor);
sendBroadcast(new Intent(BluetoothTrackingService.ACTION_CONFIG_CHANGED)
.setPackage(getPackageName()));
.setPackage(getPackageName()));
reload();
Toast.makeText(MainActivity.this, pollingLabel(minutes[selected]) + " saved", Toast.LENGTH_SHORT).show();
chooseColor(record, minutes[selected]);
@@ -219,7 +205,7 @@ public class MainActivity extends Activity implements ItemActionListener {
public void onClick(DialogInterface dialog, int selected) {
db.updateTracking(record.address, minutes, colors[selected]);
sendBroadcast(new Intent(BluetoothTrackingService.ACTION_CONFIG_CHANGED)
.setPackage(getPackageName()));
.setPackage(getPackageName()));
reload();
}
}).show();
@@ -228,7 +214,7 @@ public class MainActivity extends Activity implements ItemActionListener {
private void takePhoto() {
try { startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE), CAMERA); }
catch (Exception e) { Toast.makeText(this, "No camera app available",
Toast.LENGTH_LONG).show(); }
Toast.LENGTH_LONG).show(); }
}
protected void onActivityResult(int request, int result, Intent data) {
@@ -244,7 +230,7 @@ public class MainActivity extends Activity implements ItemActionListener {
((Bitmap) value).compress(Bitmap.CompressFormat.JPEG, 92, output);
output.close();
db.updateProfile(editing.address, null, file.getAbsolutePath(),
editing.iconPreset);
editing.iconPreset);
reload();
} catch (IOException error) {
Toast.makeText(this, "Could not save photo", Toast.LENGTH_LONG).show();
@@ -262,14 +248,14 @@ public class MainActivity extends Activity implements ItemActionListener {
.setItems(new String[] { background, "Disconnect alert notifications",
"Allow location all the time", "Background running / app settings",
"Per-item tracking information" }, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (which == 0) requestBackgroundProtection();
else if (which == 1) openNotificationSettings();
else if (which == 2) openAppSettings("Open Permissions > Location and choose Allow all the time");
else if (which == 3) openAppSettings("Allow background activity and notifications for continuous tracking");
else showTrackingInformation();
}
}).setNegativeButton("CLOSE", null).show();
public void onClick(DialogInterface dialog, int which) {
if (which == 0) requestBackgroundProtection();
else if (which == 1) openNotificationSettings();
else if (which == 2) openAppSettings("Open Permissions > Location and choose Allow all the time");
else if (which == 3) openAppSettings("Allow background activity and notifications for continuous tracking");
else showTrackingInformation();
}
}).setNegativeButton("CLOSE", null).show();
}
private void openNotificationSettings() {
@@ -348,10 +334,10 @@ public class MainActivity extends Activity implements ItemActionListener {
if (permissions.size() > 0) {
try {
Method method = Activity.class.getMethod("requestPermissions",
String[].class, Integer.TYPE);
String[].class, Integer.TYPE);
method.invoke(this, new Object[] {
permissions.toArray(new String[permissions.size()]),
Integer.valueOf(PERMISSIONS) });
permissions.toArray(new String[permissions.size()]),
Integer.valueOf(PERMISSIONS) });
} catch (Exception ignored) { }
}
}
@@ -375,3 +361,4 @@ public class MainActivity extends Activity implements ItemActionListener {
startService(intent);
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -17,6 +17,12 @@ public class TrackerDatabase extends SQLiteOpenHelper {
super(context, DB_NAME, null, DB_VERSION);
}
public List<LocationPoint> history(String address, long historyFrom, long historyTo)
{
// TODO: Implement this method
return null;
}
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE devices (address TEXT PRIMARY KEY,name TEXT," +
"connected INTEGER NOT NULL DEFAULT 0,connected_at INTEGER DEFAULT 0," +