AltBeacon 库后台服务
AltBeacon library background service
这是我用来检测进入区域事件的示例代码:
public class BeaconApplication extends android.app.Application implements BootstrapNotifier {
private static final String TAG = "TAGTAG";
@Override public void onCreate() {
super.onCreate();
Log.d(TAG, "App started up");
new BackgroundPowerSaver(this);
new RegionBootstrap(this, new Region(getPackageName(), null, null, null));
}
@Override public void didDetermineStateForRegion(int arg0, Region arg1) {
Log.d(TAG, "didDetermineStateForRegion");
}
@Override public void didEnterRegion(Region arg0) {
Log.d(TAG, "didEnterRegion");
}
@Override public void didExitRegion(Region arg0) {
Log.d(TAG, "didExitRegion");
}
}
问题在于,如果我使用以下 build.gradle 配置,那么一切都会像预期的那样工作
compileSdkVersion 21
buildToolsVersion "21.0.0"
defaultConfig {
applicationId "com.test"
minSdkVersion 18
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
LogCat:
D/TAGTAG: App started up
D/TAGTAG: didDetermineStateForRegion
D/TAGTAG: didEnterRegion
但如果我将 compileSdkVersion
更改为实际版本,则没有任何效果
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.test"
minSdkVersion 18
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
LogCat:
D/TAGTAG: App started up
从 Android 6.0 Marshmallow 开始,扫描蓝牙 LE 设备(包括信标)的应用程序必须先获得动态位置权限才能这样做。 对于遗留用途,该目标上的应用 运行 旧 Android SDK(在 API 23 之前)仍然允许扫描蓝牙 LE 设备,但仅限于前台。如果您以 SDK 21 而非 SDK 23 为目标,这就是您的应用程序运行的原因。
要在针对 SDK 23 时解决此问题,您只需添加动态权限请求即可。
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Android M Permission check
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect beacons.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override?
public void onDismiss(DialogInterface dialog) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);?
}
});
builder.show();
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_COARSE_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "coarse location permission granted");
} else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
return;
}
}
}
此处提供了有关如何执行此操作的详细说明:https://altbeacon.github.io/android-beacon-library/requesting_permission.html
我在这里写了一篇关于这个主题的博客post:http://developer.radiusnetworks.com/2015/09/29/is-your-beacon-app-ready-for-android-6.html
编辑: 正如@Near1999 在下面的评论中指出的那样,一些 Android 5+ 版本也不会检测到 BLE 设备,除非在设置中打开定位服务。显然,此限制也仅适用于针对 SDK 23+ 的情况。有关详细信息,请参阅此处:https://github.com/AltBeacon/android-beacon-library/issues/301
这是我用来检测进入区域事件的示例代码:
public class BeaconApplication extends android.app.Application implements BootstrapNotifier {
private static final String TAG = "TAGTAG";
@Override public void onCreate() {
super.onCreate();
Log.d(TAG, "App started up");
new BackgroundPowerSaver(this);
new RegionBootstrap(this, new Region(getPackageName(), null, null, null));
}
@Override public void didDetermineStateForRegion(int arg0, Region arg1) {
Log.d(TAG, "didDetermineStateForRegion");
}
@Override public void didEnterRegion(Region arg0) {
Log.d(TAG, "didEnterRegion");
}
@Override public void didExitRegion(Region arg0) {
Log.d(TAG, "didExitRegion");
}
}
问题在于,如果我使用以下 build.gradle 配置,那么一切都会像预期的那样工作
compileSdkVersion 21
buildToolsVersion "21.0.0"
defaultConfig {
applicationId "com.test"
minSdkVersion 18
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
LogCat:
D/TAGTAG: App started up
D/TAGTAG: didDetermineStateForRegion
D/TAGTAG: didEnterRegion
但如果我将 compileSdkVersion
更改为实际版本,则没有任何效果
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.test"
minSdkVersion 18
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
LogCat:
D/TAGTAG: App started up
从 Android 6.0 Marshmallow 开始,扫描蓝牙 LE 设备(包括信标)的应用程序必须先获得动态位置权限才能这样做。 对于遗留用途,该目标上的应用 运行 旧 Android SDK(在 API 23 之前)仍然允许扫描蓝牙 LE 设备,但仅限于前台。如果您以 SDK 21 而非 SDK 23 为目标,这就是您的应用程序运行的原因。
要在针对 SDK 23 时解决此问题,您只需添加动态权限请求即可。
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Android M Permission check
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect beacons.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override?
public void onDismiss(DialogInterface dialog) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);?
}
});
builder.show();
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_COARSE_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "coarse location permission granted");
} else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
return;
}
}
}
此处提供了有关如何执行此操作的详细说明:https://altbeacon.github.io/android-beacon-library/requesting_permission.html
我在这里写了一篇关于这个主题的博客post:http://developer.radiusnetworks.com/2015/09/29/is-your-beacon-app-ready-for-android-6.html
编辑: 正如@Near1999 在下面的评论中指出的那样,一些 Android 5+ 版本也不会检测到 BLE 设备,除非在设置中打开定位服务。显然,此限制也仅适用于针对 SDK 23+ 的情况。有关详细信息,请参阅此处:https://github.com/AltBeacon/android-beacon-library/issues/301