I have using Android Beacon Library for one of my beacon solution .Is there a way put a delay in data produced by the range notifier because it is giving data very frequently .
Below is the code which I am referring to. To see complete code you can go to this thread "Android iBeacon App not working in the background"
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if(beacons.size() > 0) {
for (Beacon beacon : beacons) {
if (beacon.getDistance() < 1.0) {
Log.d(TAG, "I see a beacon transmitting a : " +
" approximately " + beacon.getDistance() + " meters away.");
Log.d(TAG, "BEACON DATA : " +beacon.getBluetoothAddress()+":"+beacon.getBluetoothName()+":"+beacon.getId1());
showNotification("Treewalker","You are near beacon range");
Intent intent = new Intent(this,MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent);
}
}
}
}
There are two methods which can help you
mBeaconManager.setBackgroundBetweenScanPeriod(10000);
mBeaconManager.setForegroundBetweenScanPeriod(10000);
Check official javadocs for details
Related
I am using AltBeacon library to detect nearby beacons. The app works and is able to detect my beacons. However, it is not able to calculate distance - I am getting distance measurement value as "Infinity".
This is my code :
beaconManager.setForegroundScanPeriod(5100l);
beaconManager.setForegroundBetweenScanPeriod(11000l);
if (beacons.size() > 0) {
Log.i("Ranging", "inside detected : " + beacons.iterator().next().getDistance());
for (Beacon beacon : beacons) {
Log.i("RangingActivity", "Got rssi as : " + beacon.getRssi() + " and distance " + beacon.getDistance());
}
}
I get the following output in the log:
Got rssi as -53 and distance Infinity
What is going wrong in the distance measurement?
I am using the AltBeacon sample app on my android device - the sample app provided by altbeacon.org is here: https://github.com/AltBeacon/android-beacon-library-reference
However, the app when launched is detecting and displaying only one beacon. I have about 5 beacons near my Android device. How do I detect all the beacons?
In RangingActivity.java, I noticed this method that is being called when a beacon comes in sight:
public void onBeaconServiceConnect() {
beaconManager.setRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if (beacons.size() > 0) {
EditText editText = (EditText) RangingActivity.this.findViewById(R.id.rangingText);
Beacon firstBeacon = beacons.iterator().next();
logToDisplay("The first beacon " + firstBeacon.toString() + " is about " + firstBeacon.getDistance() + " meters away.");
}
}
}
I modified the iterator to read from the collection in a while loop as follows:
Beacon firstBeacon;
while(beacons.iterator().hasNext()){
firstBeacon = beacons.iterator().next();
logToDisplay("The first beacon " + firstBeacon.toString() + " is about " + firstBeacon.getDistance() + " meters away.");
}
However, the app crashes with this modification.
My questions:
(1) How can I display all beacons that are near my Android device?
(2) How can I detect beacons that go out of region?
For 1. I think you need to use a For loop. Like this.
for (Beacon beacon : beacons) {
logToDisplay("The beacon " + beacon.toString() + " is about " + beacon.getDistance() + " meters away.");
}
For 2. I was having trouble detecting that, but it might be a long timeout. So be very patient. I think the code in the Monitoring activity can be altered to display a message for that. Or you can review the logcat from a device.
A simple logToDisplay can be used inside the didExitRegion section of BeaconReferenceApplication.
public void didExitRegion(Region region) {
if (monitoringActivity != null) {
monitoringActivity.logToDisplay("I no longer see a beacon in the "+region.getUniqueId());
}
}
I am struggling with the accelerometer sampling rate of my app.
So I decided to develope a little app just for testing the sampling rate.
Are there any mistakes in my code? The sampling rate is pretty much changing :-/
private PowerManager.WakeLock mWakeLock;
private TextView infotext;
private SensorManager sensorManager;
private long nanoNow;
private long nanoOld;
private long nanodiffsum=0;
private int i=0;
private int values=2000;
private long[] nanodiff=new long[values];
DescriptiveStatistics myDescrStat = new DescriptiveStatistics();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int tid=android.os.Process.myTid()
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
infotext = (TextView) findViewById(R.id.textView);
sensorManager=(SensorManager)getSystemService(SENSOR_SERVICE);
sensorManager.registerListener(this,sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_FASTEST);
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
mWakeLock.acquire();
}
public void onSensorChanged(SensorEvent event){
if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
if (i==0){
nanoOld=event.timestamp;
}
if (i == values) {
for (int i=1; i<nanodiff.length; i++){
myDescrStat.addValue(nanodiff[i]);
nanodiffsum+=nanodiff[i];
}
infotext.setText(
"Average:" + nanodiffsum / values + "ms\n" + " = " + (double) 1000 / (nanodiffsum /values) + "Hz" + "\n" +
"mean: " + 1000 / myDescrStat.getMean() + "\n" +
"std:" + 1000 / myDescrStat.getStandardDeviation() + "\n" +
"max:" + 1000 / myDescrStat.getMin() + "\n" +
"min:" + 1000 / myDescrStat.getMax() + "\n");
mWakeLock.release();
sensorManager.unregisterListener(this);
}else{
nanoNow=event.timestamp;
nanodiff[i]=(nanoNow-nanoOld)/1000000;
if (i%20==0)
infotext.setText("Aktuell: " + nanodiff[i] + "ms" + " = " + Math.round((double)1000/ nanodiff[i]) + "Hz" );
nanoOld=nanoNow;
i++;
}
}
}
Kindly regards,
Arthur
After a cursory look at your code I cannot see anything wrong with it (except perhaps the overzealous update of the thread priority, which makes sense in a testing app but I wouldn't use without a good reason in actual production code).
As for the irregular rate of the the SensorManager's data (spoiler alert: the same behavior applies to other sensor streams ;-) ), it is meant to be that way, and the frequency specified with SensorManager.SENSOR_DELAY_FASTEST is meant to be only a hint (which is the reason why actually you receive the time of the measurement with such accuracy at each event). This is stated in the official documentation:
rateUs : The rate sensor events are delivered at. This is only a hint to the system.
Events may be received faster or slower than the specified rate. Usually events are received faster. Source: registerListener reference page
For one part, keep in mind that Android is Linux at the core, and linux is not a real-time system (and therefore can't provide data with realtime accuracy); on the other side, Android has to cope with a lot of different hardware implementations (and sensor brands), therefore the Android developers team has probably done a wise choice to avoid any kind of commitment about the ratio of the sensor data.
Those are my 50 cents, if you want to get serious about Android Sensors programming I would suggest this book:
Professional Android Sensor Programming (Greg Milette, Adam Stroud)
I read about 1/4 of it and so far, so good (I'm in no way related to the publisher or the author).
Hope this helps
I am working with iBeacons and using the AltBeacon library.
beaconManager.getBeaconParsers()
.add(new BeaconParser()
.setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
I would like my Android app to detect and generate an event when beacons enter and exit visibility.
This works just fine fine with a single beacon using the library using methods.
public void **didEnterRegion**(Region region)
and
public void **didExitRegion**(Region region)
My problem is when multiple beacons are visible at the same time.
I am trying to maintain an array with all beacons visible.
I want to generate an event each time a beacon enters and exits.
The event should identify the beacon that generated the event by it's unique Identifier.
My beacons are uniquely identifiable using the beacon.getIdentifiers() or (UUID, Major and Minor)
The problem is that the didExitRegion method does not get executed until all beacons exit the region.
Can anyone think of a simple way for me to achieve my goals using AltBeacon library?
Any suggestions would be greatly appreciated.
Two options:
Set up a different region to match only each individual beacon, specifying all their identifiers, and monitor for each. You will get a different entry and exit callback for each region.
Region region1 = new Region("myIdentifier1", Identifier.parse("2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6"), Identifier.parse("1"), Identifier.parse("1"));
Region region2 = new Region("myIdentifier2", Identifier.parse("2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6"), Identifier.parse("1"), Identifier.parse("2"));
beaconManager.startMonitoringBeaconsInRegion(region1);
beaconManager.startMonitoringBeaconsInRegion(region2);
Enable ranging, and put code in the didRangeBeaconsInRegion callback to track individual beacons. You can use a java.util.HashMap to keep track of all beacons that are visible (with a timestamp for the latest time each was seen), and then if you haven't seen a beacon in, say, five seconds, you can remove the beacon from the HashMap and execute your exit logic for that beacon.
Option 1 is great for a small number of beacons where you know their identifiers up front. Option 2 is more involved, but better for a large number of beacons or if you do not know their identifiers in advance.
/***************This Code for estimote Beacons *****************/
private final Region ALL_ESTIMOTE_BEACONS_REGION = new Region("beaconall", null, null, null);
private BeaconManager beaconManager;
public onCreate()
{
beaconManager.connect(new BeaconManager.ServiceReadyCallback()
{
#Override
public void onServiceReady()
{
Log.d("Lalit", "Beacon service Ready");
beaconManager.startRanging(ALL_ESTIMOTE_BEACONS_REGION);
beaconManager.startMonitoring(ALL_ESTIMOTE_BEACONS_REGION);
}
});
beaconManager.setRangingListener(new BeaconManager.RangingListener() {
#Override
public void onBeaconsDiscovered(Region region, final List<Beacon> beacons) {
int index = beacons.size();
// UUID uuid = UUID.fromString("");
if (beacons.size() > 0) {
Beacon SelectedBeacon = beacons.get(index-1);
Log.d("Lalit", "Beacon Id :- " + SelectedBeacon.getProximityUUID());
Log.d("Lalit", "Beacon major :- " + SelectedBeacon.getMajor());
Log.d("Lalit", "Beacon miner :- " + SelectedBeacon.getMinor());
Log.d("Lalit", "Beacon total :- " + beacons.size());
Log.d("Lalit","Distance :- "+ getDistance(SelectedBeacon.getRssi(),SelectedBeacon.getMeasuredPower()));
}
}
});
beaconManager.setMonitoringListener(new BeaconManager.MonitoringListener() {
#Override
public void onEnteredRegion(Region region, List<Beacon> list) {
Calendar calendar = Calendar.getInstance();
Date entertime = calendar.getTime();
Log.d("Lalit", "Region Enter :- " + entertime);
Log.d("List", "Region UUID id :- " + region.getProximityUUID());
}
#Override
public void onExitedRegion(Region region) {
Calendar calendar = Calendar.getInstance();
Date entertime = calendar.getTime();
Log.d("Lalit", "Region exit :- " + entertime);
Log.d("List", "Region UUID id :- " + region.getProximityUUID());
}
});
}
When the android text to speech functionality translates audio waves to text, is it possible to determine the 'confidence levels' of spoken text? So for example, if someone speaks too far away from the mic and the android device picks up distorted sounds, would it both output translated text along with a low confidence interval to state it isn't sure how accurate that particular translation was.
if you are implementing the RecognitionListener examine this code clip from my onResults method.
#Override
public void onResults(Bundle results) {
String LOG = "SpeechRecognizerActivity"
Log.d(LOG, "onResults");
ArrayList<String> strlist = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
float [] confidence = results.getFloatArray(SpeechRecognizer.CONFIDENCE_SCORES);
for (int i = 0; i < strlist.size(); i++) {
Log.d(LOG, "result=" + strlist.get(i));
}
Log.d(LOG + " result", strlist.get(0));
if (confidence != null){
if (confidence.length > 0){
Log.d(LOG + " confidence", String.valueOf(confidence[0]));
} else {
Log.d(LOG + " confidence score not available", "unknown confidence");
}
} else {
Log.d(LOG, "confidence not found");
}
}
You won't see anything unless you add this to your recognizer intent:
iSpeechIntent.putExtra(RecognizerIntent.EXTRA_CONFIDENCE_SCORES, true);
Yes. In the returned Bundle, there's a float array called CONFIDENCE_SCORES. From the docs:
Key used to retrieve a float array from the Bundle passed to the onResults(Bundle) and onPartialResults(Bundle) methods. The array should be the same size as the ArrayList provided in RESULTS_RECOGNITION, and should contain values ranging from 0.0 to 1.0, or -1 to represent an unavailable confidence score.
Confidence values close to 1.0 indicate high confidence (the speech recognizer is confident that the recognition result is correct), while values close to 0.0 indicate low confidence.
This value is optional and might not be provided.
Please note that it is not guaranteed to be there. Check for it and use if present. Gamble if not.