Android: AltBeacon 未检测到信标
Android: AltBeacon not detecting beacons
我正在使用此处的 AltBeacon 库开发一个简单的信标接近应用程序
https://altbeacon.github.io/android-beacon-library/samples.html
我正在试验上述网站上提供的示例代码,但是,每次我 运行 应用程序都只转到 didDetermineStateForRegion() 方法。如果它检测到信标,它将转到 didEnterRegion() 方法。
我不确定自己做错了什么,也无法在其他问题中找到答案。
上述网站上提供的参考应用程序也存在同样的问题,但定位应用程序(基于 AltBeacon)会立即检测到我的信标。
我的beacon设置为152ms传输间隔和最大传输功率。
这是我的代码:
主要活动
public class MainActivity extends AppCompatActivity implements BeaconConsumer {
protected final String TAG = "Beacons Monitoring";
private BeaconManager beaconManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22-23,p:24-24"));
beaconManager.bind(this);
}
public void onDestroy(){
super.onDestroy();
beaconManager.unbind(this);
}
@Override
public void onBeaconServiceConnect() {
beaconManager.addMonitorNotifier(new MonitorNotifier() {
@Override
public void didEnterRegion(Region region) {
Log.e(TAG,"I just saw a beacon for the first time");
}
@Override
public void didExitRegion(Region region) {
Log.e(TAG, "I lost my beacons :( ");
}
@Override
public void didDetermineStateForRegion(int i, Region region) {
Log.e(TAG, "I just switched from seeing/not seeing a beacon. STATE: " + i);
}
});
try {
beaconManager.startMonitoringBeaconsInRegion(new Region("myMonitoringUniqueId", null, null, null));
} catch (RemoteException e){
Log.e(TAG, "EXCEPTION!!! :'( ");
}
}
}
清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.michal.beacons2">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
有谁知道我的代码有什么问题吗?
了解 didEnterRegion
回调 只有当您 尚未 在区域 时才会触发。这意味着如果在开发过程中重新启动应用程序时信标正在传输,您将不会收到新的回调。当应用程序重新启动时,您将始终收到 didDetermineStateForRegion()
的新回调。
为什么会这样?因为 Android 经常会因为 low-memory 条件临时杀死应用程序,并且库会在几分钟后自动重启它们以继续寻找信标。如果库没有以这种方式工作,则每次应用程序被 Android OS 暂时停止并稍后重新启动时,应用程序都会重复获得对 didEnterRegion
的回调,即使信标从未消失又出现。
这在开发过程中可能会令人沮丧,因此可以使用以下代码禁用此功能:
beaconManager.setRegionStatePeristenceEnabled(false)
如果您这样做,明智的做法是在投入生产之前删除此行,以防止每次应用程序被 OS.
暂时杀死时出现多次进入事件。
我设法解决了这个问题。
首先,根据您使用的信标类型设置信标布局很重要。这些是可用的布局:
ALTBEACON m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25
EDDYSTONE TLM x,s:0-1=feaa,m:2-2=20,d:3-3,d:4-5,d:6-7,d:8-11,d:12-15
EDDYSTONE UID s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19
EDDYSTONE URL s:0-1=feaa,m:2-2=10,p:3-3:-41,i:4-20v
IBEACON m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24
来源:https://beaconlayout.wordpress.com/
可以使用以下代码设置布局:
beaconManager.getBeaconParsers().add(new
BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
其次,android 需要位置权限才能检测信标。我已经通过检查授予和拒绝权限时发生的情况对此进行了测试,但 Android Beacon Library 网站上也提到了这一要求。我建议按照 Google 的 Android 开发人员培训中有关获取用户许可的说明进行操作:
https://developer.android.com/training/permissions/index.html
此外,我已经测试了 davidgyoung 提供的代码,一旦我设法解决了这个问题,它确实按照描述的方式工作,所以我建议在开发阶段将它添加到您的代码中。
所有这些实际上在 Android Beacon Library 网站上都有清楚的解释,但我不知何故把一切都搞糊涂了。我希望这个答案对以后的人有所帮助。
我正在使用此处的 AltBeacon 库开发一个简单的信标接近应用程序 https://altbeacon.github.io/android-beacon-library/samples.html
我正在试验上述网站上提供的示例代码,但是,每次我 运行 应用程序都只转到 didDetermineStateForRegion() 方法。如果它检测到信标,它将转到 didEnterRegion() 方法。
我不确定自己做错了什么,也无法在其他问题中找到答案。
上述网站上提供的参考应用程序也存在同样的问题,但定位应用程序(基于 AltBeacon)会立即检测到我的信标。
我的beacon设置为152ms传输间隔和最大传输功率。
这是我的代码:
主要活动
public class MainActivity extends AppCompatActivity implements BeaconConsumer {
protected final String TAG = "Beacons Monitoring";
private BeaconManager beaconManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22-23,p:24-24"));
beaconManager.bind(this);
}
public void onDestroy(){
super.onDestroy();
beaconManager.unbind(this);
}
@Override
public void onBeaconServiceConnect() {
beaconManager.addMonitorNotifier(new MonitorNotifier() {
@Override
public void didEnterRegion(Region region) {
Log.e(TAG,"I just saw a beacon for the first time");
}
@Override
public void didExitRegion(Region region) {
Log.e(TAG, "I lost my beacons :( ");
}
@Override
public void didDetermineStateForRegion(int i, Region region) {
Log.e(TAG, "I just switched from seeing/not seeing a beacon. STATE: " + i);
}
});
try {
beaconManager.startMonitoringBeaconsInRegion(new Region("myMonitoringUniqueId", null, null, null));
} catch (RemoteException e){
Log.e(TAG, "EXCEPTION!!! :'( ");
}
}
}
清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.michal.beacons2">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
有谁知道我的代码有什么问题吗?
了解 didEnterRegion
回调 只有当您 尚未 在区域 时才会触发。这意味着如果在开发过程中重新启动应用程序时信标正在传输,您将不会收到新的回调。当应用程序重新启动时,您将始终收到 didDetermineStateForRegion()
的新回调。
为什么会这样?因为 Android 经常会因为 low-memory 条件临时杀死应用程序,并且库会在几分钟后自动重启它们以继续寻找信标。如果库没有以这种方式工作,则每次应用程序被 Android OS 暂时停止并稍后重新启动时,应用程序都会重复获得对 didEnterRegion
的回调,即使信标从未消失又出现。
这在开发过程中可能会令人沮丧,因此可以使用以下代码禁用此功能:
beaconManager.setRegionStatePeristenceEnabled(false)
如果您这样做,明智的做法是在投入生产之前删除此行,以防止每次应用程序被 OS.
暂时杀死时出现多次进入事件。我设法解决了这个问题。
首先,根据您使用的信标类型设置信标布局很重要。这些是可用的布局:
ALTBEACON m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25
EDDYSTONE TLM x,s:0-1=feaa,m:2-2=20,d:3-3,d:4-5,d:6-7,d:8-11,d:12-15
EDDYSTONE UID s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19
EDDYSTONE URL s:0-1=feaa,m:2-2=10,p:3-3:-41,i:4-20v
IBEACON m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24
来源:https://beaconlayout.wordpress.com/
可以使用以下代码设置布局:
beaconManager.getBeaconParsers().add(new
BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
其次,android 需要位置权限才能检测信标。我已经通过检查授予和拒绝权限时发生的情况对此进行了测试,但 Android Beacon Library 网站上也提到了这一要求。我建议按照 Google 的 Android 开发人员培训中有关获取用户许可的说明进行操作: https://developer.android.com/training/permissions/index.html
此外,我已经测试了 davidgyoung 提供的代码,一旦我设法解决了这个问题,它确实按照描述的方式工作,所以我建议在开发阶段将它添加到您的代码中。
所有这些实际上在 Android Beacon Library 网站上都有清楚的解释,但我不知何故把一切都搞糊涂了。我希望这个答案对以后的人有所帮助。