我想在我的Android应用程序中被动地扫描BLE广告商,
但我找不到如何做到这一点。
> < li>
根据蓝牙4.0核心规范,存在被动扫描模式。< br >第6卷:核心系统包[低能耗控制器卷],< br > D部分:4.1被动扫描< br > https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=282159
“设备可以使用被动扫描来查找区域中的广告设备。”
而且,android有一个决定扫描类型的参数。(主动/被动)
http://androidxref.com/4.3_r2.1/xref/external/bluetooth/bluedroid/stack/btm/btm_ble_gap.c#555
“扫描类型:主动扫描或被动扫描”
同时,iOS可以被动扫描ble广告主。(可惜仅限后台模式)< br > http://lists . apple . com/archives/bluetooth-dev/2012/May/msg 00041 . html < br >“当应用程序在后台时,iOS会执行被动扫描。”
但是我无法找到是否可以使用被动扫描模式。
问:是否可以在Android上使用“被动扫描”?如果可能,如何使用此功能?
在AOSP存储库中找到btif_gatt_client.c,编辑它,
取代
BTM_BleSetScanParams(p_cb->scan_interval, p_cb->scan_window, BTM_BLE_SCAN_MODE_ACTI);
与
BTM_BleSetScanParams(p_cb->scan_interval, p_cb->scan_window, BTM_BLE_SCAN_MODE_PASS);
然后构建AOSP,将图像闪存到手机,然后被动扫描工作。
< code >主动和< code >被动扫描的区别在于< code >主动扫描向广告商请求一个< code>SCAN_RESPONSE数据包。这是通过在检测到广告后发送一个< code>SCAN_REQUEST包来完成的。两者的信息(有效载荷)将在设备发现回调的< code>scanRecord参数中。
从核心规范来看:
设备可以使用主动扫描来获得关于设备的更多信息,这些信息对于填充用户界面可能是有用的。主动扫描涉及更多的链路层广告消息。
因此,对于任何用例,没有必要区分这两种扫描类型。
但是,如果您想在后台侦听广告,那么您需要通过创建服务
来自己执行此操作 - 没有内置功能(从Android 4.4开始)。
对于背景扫描,以此为例。但是扫描会在你的应用被系统终止(或者被用户停止)的时候结束。
通过AlarmManager启动PendingEvent(应用程序中的任何位置,必须至少运行一次才能启动服务…)
AlarmManager alarmMgr = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getActivity(), BleScanService.class);
PendingIntent scanIntent = PendingIntent.getService(getActivity(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime(), intervalMillis, scanIntent);
BleScanService
public class BleScanService extends Service implements LeScanCallback {
private final static String TAG = BleScanService.class.getSimpleName();
private final IBinder mBinder = new LocalBinder();
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
public class LocalBinder extends Binder {
public BleScanService getService() {
return BleScanService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
@Override
public void onCreate() {
super.onCreate();
initialize();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
long timeToScan = preferences.scanLength().get();
startScan(timeToScan);
return super.onStartCommand(intent, flags, startId);
}
/**
* Initializes a reference to the local bluetooth adapter.
*
* @return Return true if the initialization is successful.
*/
public boolean initialize() {
// For API level 18 and above, get a reference to BluetoothAdapter
// through
// BluetoothManager.
if (mBluetoothManager == null) {
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager == null) {
Log.e(TAG, "Unable to initialize BluetoothManager.");
return false;
}
}
if (mBluetoothAdapter == null) {
mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
return false;
}
}
Log.d(TAG, "Initialzed scanner.");
return true;
}
/**
* Checks if bluetooth is correctly set up.
*
* @return
*/
protected boolean isInitialized() {
return mBluetoothManager != null && mBluetoothAdapter != null && mBluetoothAdapter.isEnabled();
}
/**
* Checks if ble is ready and bluetooth is correctly setup.
*
* @return
*/
protected boolean isReady() {
return isInitialized() && isBleReady();
}
/**
* Checks if the device is ble ready.
*
* @return
*/
protected boolean isBleReady() {
return getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
}
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
Log.d(TAG, "Found ble device " + device.getName() + " " + device.getAddress());
broadcastOnDeviceFound(device, scanRecord);
}
/**
* Broadcasts a message with the given device.
*
* @param device
* @param scanRecord
*/
protected void broadcastOnDeviceFound(final BluetoothDevice device, byte[] scanRecord) {
assert device != null : "Device should not be null.";
Intent intent = new Intent(BleServiceConstants.ACTION_DEVICE_DISCOVERED);
intent.putExtra(BleServiceConstants.EXTRA_DEVICE_DISCOVERED_DEVICE, device);
intent.putExtra(BleServiceConstants.EXTRA_DEVICE_DISCOVERED_SCAN_RECORD, scanRecord);
sendBroadcast(intent);
}
/**
* Starts the bluetooth low energy scan It scans at least the
* delayStopTimeInMillis.
*
* @param delayStopTimeInMillis
* the duration of the scan
* @return <code>true</code> if the scan is successfully started.
*/
public boolean startScan(long delayStopTimeInMillis) {
if (!isReady())
return false;
if (preferences.shouldScan().get()) {
if (delayStopTimeInMillis <= 0) {
Log.w(TAG, "Did not start scanning with automatic stop delay time of " + delayStopTimeInMillis);
return false;
}
Log.d(TAG, "Auto-Stop scan after " + delayStopTimeInMillis + " ms");
getMainHandler().postDelayed(new Runnable() {
@Override
public void run() {
Log.d(TAG, "Stopped scan.");
stopScan();
}
}, delayStopTimeInMillis);
}
return startScan();
}
/**
* @return an handler with the main (ui) looper.
*/
private Handler getMainHandler() {
return new Handler(getMainLooper());
}
/**
* Starts the bluetooth low energy scan. It scans without time limit.
*
* @return <code>true</code> if the scan is successfully started.
*/
public boolean startScan() {
if (!isReady())
return false;
if (preferences.shouldScan().get()) {
if (mBluetoothAdapter != null) {
Log.d(TAG, "Started scan.");
return mBluetoothAdapter.startLeScan(this);
} else {
Log.d(TAG, "BluetoothAdapter is null.");
return false;
}
}
return false;
}
/**
* Stops the bluetooth low energy scan.
*/
public void stopScan() {
if (!isReady())
return;
if (mBluetoothAdapter != null)
mBluetoothAdapter.stopLeScan(this);
else {
Log.d(TAG, "BluetoothAdapter is null.");
}
}
@Override
public void onDestroy() {
preferences.edit().shouldScan().put(false).apply();
super.onDestroy();
}
}
常量只是用于分发意向操作和额外名称的字符串。还有另一个首选项存储存储扫描阶段应该多长时间...您可以根据需要轻松替换它。
然后,您必须使用与上述操作名称(< code>BleServiceConstants)匹配的意图过滤器注册一个广播接收器。操作设备发现)
public class DeviceWatcher extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
BluetoothDevice device = intent.getParcelableExtra(BleServiceConstants.EXTRA_DEVICE_DISCOVERED_DEVICE);
// do anything with this information
}
}
我正在Android(移动设备a)上执行UUID过滤扫描,我有两个测试用例。 一个人在另一个Android设备(移动设备b)上使用一个名为BLE扫描仪的应用程序来创建一个具有两个测试服务的BLE服务器(每个服务都有自己唯一的UUID)。另一种是通过Arduino BLE服务器,为其服务定制UUID。 如果我使用移动设备B的BLE扫描仪应用程序并扫描arduino,我可以找到它,连接到它并查看服务以
我必须构建一个Android应用程序,用于读取一种设备上的信息,该设备仅在过滤时在扫描时显示(一般扫描不会显示它)。该设备类似于信标,因此它仅通告数据,这些数据在通告上具有我想要的信息(它不可连接)。制造商给我的过滤器是原始数据。即: 0x02010612435542 我不能按名称过滤它,因为设备不会宣传它的名称。我也不能通过来完成,因为应用程序以前不会知道设备的地址(这将是许多此类设备)。 nr
我试图从用户那里得到2个整数。这是我的代码的相关部分: 起初,它抛出一个,所以我使用了。现在,它只需跳过扫描器并立即调用。
我必须建立一个应用程序,扫描BLE设备,并返回它的数据。扫描时设备不会显示,除非我使用过滤器。 UUID 不是一个选项,设备不会广播其名称(使用 扫描时会显示 N/A。 我正在尝试按MAC地址扫描它。但是,我不知道MAC地址,因为它可以是任何类型的设备,所以应用程序之前不会知道设备的MAC地址。 我已经知道设备的地址上有一个前缀,即。问题是后缀。我如何(如果可能的话)制作一个正则表达式作为参数传递
本文向大家介绍扫二维码下载apk并统计被扫描次数,包括了扫二维码下载apk并统计被扫描次数的使用技巧和注意事项,需要的朋友参考一下 需求:想让用户扫描一个二维码就能下载APP,并统计被扫描次数。 两种实现方法: 1.一般我们用草料生成二维码,如果没有注册的话只能生成一个包含下载网址的静态码,没有统计功能,而且出了自己截图保存外,草料是不会保存你的二维码的。 如果注册草料后,可以选择生成活码。所谓活
您可以通过Burp 控制台(Burp Dashboard)上的新的扫描(New scan)按钮或是 Burp 中出现的菜单中的Scan选项来启动扫描。利用这些方法可打开扫描启动窗口,然后您可以使用它配置扫描中的各种详细参数。 扫描细节 扫描启动界面的详细的扫描信息(Scan details)部分允许您选择扫描类型,配置要扫描的内容等等信息。 扫描类型 您可以选择以下扫描类型: 抓取并审计(Craw