dav*_*ung 23 android bluetooth-lowenergy android-bluetooth android-6.0-marshmallow
以下代码适用于运行Android 5.1.1(Build LMY48M)的Nexus 9,但不适用于运行Android 6.0的Nexus 9(Build MPA44l)
List<ScanFilter> filters = new ArrayList<ScanFilter>();
ScanSettings settings = (new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)).build();
ScanFilter.Builder builder = new ScanFilter.Builder();
builder.setManufacturerData((int) 0x0118, new byte[]{(byte) 0xbe, (byte) 0xac}, new byte[]{(byte) 0xff, (byte)0xff});
ScanFilter scanFilter = builder.build();
filters.add(scanFilter);
mBluetoothLeScanner.startScan(filters, settings, new ScanCallback() {
...
});
Run Code Online (Sandbox Code Playgroud)
在Android 5.x上,当看到与扫描过滤器匹配的制造商广告时,上述代码产生回调.(参见下面的示例Logcat输出.)在带有MPA44l的Nexus 9上,没有收到回调.如果您注释掉扫描过滤器,则会在Nexus 9上成功接收回调.
09-22 00:07:28.050 1748-1796/org.altbeacon.beaconreference D/BluetoothLeScanner? onScanResult() - ScanResult{mDevice=00:07:80:03:89:8C, mScanRecord=ScanRecord [mAdvertiseFlags=6, mServiceUuids=null, mManufacturerSpecificData={280=[-66, -84, 47, 35, 68, 84, -49, 109, 74, 15, -83, -14, -12, -111, 27, -87, -1, -90, 0, 1, 0, 1, -66, 0]}, mServiceData={}, mTxPowerLevel=-2147483648, mDeviceName=null], mRssi=-64, mTimestampNanos=61272522487278}
Run Code Online (Sandbox Code Playgroud)
有没有人看过ScanFilters在Android M上工作?
din*_*aur 31
我的应用程序连接到蓝牙也有类似的问题.不是LE ScanFilter,但它是一个权限问题,就像OP一样.
根本原因在于,首先是SDK 23,你需要提示用户在系统运行时的权限Activity的requestPermissions()方法.
这对我有用:
AndroidManifest.xml在根节点内添加以下两行之一:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Run Code Online (Sandbox Code Playgroud)在你的活动,试图连接到蓝牙之前,调用Activity的requestPermissions()方法,这将打开一个系统对话框,以提示输入权限的用户.权限对话框在另一个线程中打开,因此在尝试连接到蓝牙之前一定要等待结果.
覆盖Activity的onRequestPermissionsResult()处理结果.如果用户拒绝授予权限,该方法实际上只需要做一些事情,告诉用户应用程序不能进行蓝牙活动.
这篇博文有一些示例代码,它使用AlertDialogs告诉用户发生了什么.这是一个很好的起点,但有一些缺点:
requestPermissions()线程完成requestPermissions()对我来说似乎无关紧要.裸露的电话requestPermissions()就足够了.dav*_*ung 20
问题不在于扫描过滤器,而是在应用程序在后台时才使用扫描过滤器.从Android M开始,除非应用具有以下两种权限之一,否则后台蓝牙LE扫描将被阻止:
android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_FINE_LOCATION
Run Code Online (Sandbox Code Playgroud)
我正在测试的应用程序没有请求这些权限中的任何一个,因此它在Android M后台(在扫描过滤器处于活动状态的唯一时间)不起作用.添加第一个解决了问题.
我意识到这是问题,因为我在Logcat中看到以下行:
09-22 22:35:20.152 5158 5254 E BluetoothUtils: Permission denial: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅此处:https: //code.google.com/p/android-developer-preview/issues/detail?id = 2964
Hit*_*ahu 10
添加位置权限以及BLE
Run Code Online (Sandbox Code Playgroud)<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
复制粘贴此方法以请求和授予位置权限
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: {
Map<String, Integer> perms = new HashMap<String, Integer>();
// Initial
perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
// Fill with results
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
// Check for ACCESS_FINE_LOCATION
if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
) {
// All Permissions Granted
// Permission Denied
Toast.makeText(ScanningActivity.this, "All Permission GRANTED !! Thank You :)", Toast.LENGTH_SHORT)
.show();
} else {
// Permission Denied
Toast.makeText(ScanningActivity.this, "One or More Permissions are DENIED Exiting App :(", Toast.LENGTH_SHORT)
.show();
finish();
}
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
@TargetApi(Build.VERSION_CODES.M)
private void fuckMarshMallow() {
List<String> permissionsNeeded = new ArrayList<String>();
final List<String> permissionsList = new ArrayList<String>();
if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
permissionsNeeded.add("Show Location");
if (permissionsList.size() > 0) {
if (permissionsNeeded.size() > 0) {
// Need Rationale
String message = "App need access to " + permissionsNeeded.get(0);
for (int i = 1; i < permissionsNeeded.size(); i++)
message = message + ", " + permissionsNeeded.get(i);
showMessageOKCancel(message,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
}
});
return;
}
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
return;
}
Toast.makeText(ScanningActivity.this, "No new Permission Required- Launching App .You are Awesome!!", Toast.LENGTH_SHORT)
.show();
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(ScanningActivity.this)
.setMessage(message)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null)
.create()
.show();
}
@TargetApi(Build.VERSION_CODES.M)
private boolean addPermission(List<String> permissionsList, String permission) {
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(permission);
// Check for Rationale Option
if (!shouldShowRequestPermissionRationale(permission))
return false;
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
然后在onCreate上检查是否允许
if (Build.VERSION.SDK_INT >= 23) {
// Marshmallow+ Permission APIs
fuckMarshMallow();
}
Run Code Online (Sandbox Code Playgroud)
希望它能节省您的时间.
| 归档时间: |
|
| 查看次数: |
33911 次 |
| 最近记录: |