首页 > 解决方案 > 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());
    }
}

}

标签: androidandroid-bluetoothbeacon

解决方案


推荐阅读