android - on App resume beaconmanager 无法使用 Android 信标库检测信标
问题描述
我第一次运行应用程序信标监控和测距工作正常。但是我第二次启动应用程序时,即在调用 onResume 之后它只显示以下并且不再调用 didRangeBeaconsInRegion :我猜这是因为 beaconManager 实例未正确销毁或调用 onDestroy 中的某些东西。但是,根据库示例,我尝试在 onPause() 中取消绑定但没有成功。任何想法 ?
I/MonitoringActivity: I have just switched from seeing/not seeing beacons: 0
2020-07-15 18:41:40.776 9657-9657/com.something.beacon I/MonitoringActivity: I have just switched from seeing/not seeing beacons: 0
2020-07-15 18:41:40.824 9657-9657/com.something.beacon I/MonitoringActivity: I have just switched from seeing/not seeing beacons: 1
public class MainActivity extends AppCompatActivity implements BeaconConsumer {
private static final int PERMISSION_REQUEST_FINE_LOCATION = 1;
private static final int PERMISSION_REQUEST_BACKGROUND_LOCATION = 2;
ListView beaconList;
protected static final String TAG = "MonitoringActivity";
private BeaconManager beaconManager;
private FirebaseDatabase database;
private DatabaseReference beaconDBRef;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Firebase database setup
database = FirebaseDatabase.getInstance();
beaconDBRef = database.getReference().child("messages");
beaconList = (ListView) findViewById(R.id.beacon_list);
Log.d(TAG, "onCreate: is called");
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
// Detect the main identifier (UID) frame:
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT));
// Detect the telemetry (TLM) frame:
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout(BeaconParser.EDDYSTONE_TLM_LAYOUT));
// Detect the URL frame:
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout(BeaconParser.EDDYSTONE_URL_LAYOUT));
beaconManager.bind(this);
verifyBluetooth();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (this.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (this.checkSelfPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
if (!this.shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_BACKGROUND_LOCATION)) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs background location access");
builder.setMessage("Please grant location access so this app can detect beacons in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@TargetApi(23)
@Override
public void onDismiss(DialogInterface dialog) {
requestPermissions(new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION},
PERMISSION_REQUEST_BACKGROUND_LOCATION);
}
});
builder.show();
}
else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since background location access has not been granted, this app will not be able to discover beacons in the background. Please go to Settings -> Applications -> Permissions and grant background location access to this app.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
}
}
} else {
if (!this.shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_BACKGROUND_LOCATION},
PERMISSION_REQUEST_FINE_LOCATION);
}
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. Please go to Settings -> Applications -> Permissions and grant location access to this app.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
}
}
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onDestroy() {
super.onDestroy();
beaconManager.unbind(this);
}
long tempTime = Integer.MIN_VALUE;
long callInterval = 10000;
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_FINE_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "fine 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 nearby devices.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
return;
}
case PERMISSION_REQUEST_BACKGROUND_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "background location permission granted");
} else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since background location access has not been granted, this app will not be able to discover devices 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;
}
}
}
private void verifyBluetooth() {
try {
if (!BeaconManager.getInstanceForApplication(this).checkAvailability()) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Bluetooth not enabled");
builder.setMessage("Please enable bluetooth in settings and restart this application.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
//finish();
//System.exit(0);
}
});
builder.show();
}
}
catch (RuntimeException e) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Bluetooth LE not available");
builder.setMessage("Sorry, this device does not support Bluetooth LE.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
//finish();
//System.exit(0);
}
});
builder.show();
}
}
@Override
public void onBeaconServiceConnect() {
// Set the two identifiers below to null to detect any beacon regardless of identifiers
Identifier myBeaconNamespaceId = Identifier.parse("0x2F234454F4911BA9FFA6");
final Identifier myBeaconInstanceId = Identifier.parse("0x000000000001");
beaconManager.removeAllMonitorNotifiers();
beaconManager.removeAllRangeNotifiers();
beaconManager.addMonitorNotifier(new MonitorNotifier() {
@Override
public void didEnterRegion(Region region) {
Log.i(TAG, "I just saw an beacon for the first time!");
try {
Log.d(TAG, "didEnterRegion");
beaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void didExitRegion(Region region) {
Log.i(TAG, "I no longer see an beacon");
try {
Log.d(TAG, "didExitRegion");
beaconManager.stopRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void didDetermineStateForRegion(int state, Region region) {
Log.i(TAG, "I have just switched from seeing/not seeing beacons: "+state);
}
});
beaconManager.addRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
for(Beacon oneBeacon : beacons) {
String beaconInfo = "Namespace id: " + oneBeacon.getId1() + "\nInstance Id: " + oneBeacon.getId2();
Log.d(TAG, beaconInfo);
Toast.makeText(MainActivity.this, beaconInfo, Toast.LENGTH_SHORT).show();
//Write to database every 10 seconds
long currentTime = System.currentTimeMillis();
if(currentTime > tempTime + callInterval){
BeaconModel beaconModel = new BeaconModel();
beaconModel.setBeaconName(oneBeacon.getId2().toString());
beaconModel.setDistance(oneBeacon.getDistance());
beaconModel.setMessage("this is a nice message");
beaconDBRef.child(beaconModel.getBeaconName()).setValue(beaconModel);
//beaconDBRef.push().setValue("beacon detected! - " + oneBeacon.getId2());
tempTime = currentTime;
}
}
}
});
try {
Identifier myBeaconNamespaceId1 = Identifier.parse("0xedd1ebeac04e5defa017");
Identifier myBeaconInstanceId1 = Identifier.parse("0x0e32fea91b13");
Identifier myBeaconInstanceId2 = Identifier.parse("0xa9937b420872");
beaconManager.startMonitoringBeaconsInRegion(new Region("myMonitoringUniqueId", myBeaconNamespaceId1, myBeaconInstanceId1, null));
beaconManager.startMonitoringBeaconsInRegion(new Region("myMonitoringUniqueId2", myBeaconNamespaceId1, myBeaconInstanceId2, null));
beaconManager.startMonitoringBeaconsInRegion(new Region("myMonitoringUniqueId3", null, null, null));
} catch (RemoteException e) {
Log.d(TAG, e.getMessage());
}
}
}
解决方案
推荐阅读
- html - 为什么 request.GET.get 不捕获这个参数?
- r - R Keras 错误:py_call_impl 中的错误(可调用,dots$args,dots$keywords):ValueError:未提供数据
- django - 在 Ajax 中显示 ValidationError
- javascript - 如何更改 Axios 响应中的变量值?
- r - 将操作数据Stata转换为R:if和递归值在同一行
- pandas - 如果满足多个条件,则保留数据框行
- javascript - 从 div 元素中删除单词
- java - 如何从命令行在 jar 文件中运行测试类?
- java - 从带有 NP 的 Python 移植到 Java - 传递给 np.sum 时,不能将序列乘以“列表”的非整数类型
- winapi - UI 自动化 ScrollPattern 是否有边界矩形或者是否有可靠的方法来获取它?