Android App not scanning for beacons after the first run - android

I am trying to build an app where the strength of the nearest beacon is detected (by the signal strength) and the corresponding API must be called (with the beacon ID as a parameter). The app asks for location the first time and runs very well (detects the nearest beacon). But after I close the app and reopen it, the beacon ID will be empty always (string2 variable is being set with beacon ID). Why is it running the first time and not subsequent times?
Whenever I clear the data of the app, the app asks for location and runs fine. I have coded the entire segment again three times and yet I encounter the same problem.
I have tried to trace the flow through log statements. I observed that onBeaconServiceConnect() method isn't executing the second time (unless the app's data is cleared).
AsyncTask:
public class Navigate extends AsyncTask<String, String, String> {
protected String doInBackground(String... strings) {
//REST Query
String cs, ps = null;
//Here bid is a field and it will be set to Beacon ID of the nearest beacon.
while (!bid.equals(strings[1])) {
try {
imageURL=callAPI("bid1","bid3");
Log.e("BeaconID", bid); //The default value of bid will be printed and not the beacon ID.
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
Log.e("Debug", "Step3");
return "none";
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
Toast.makeText(getApplicationContext(), "onProgressUpdate", Toast.LENGTH_SHORT).show();
mNetworkImageView = (NetworkImageView) findViewById(R.id.mapImage);
mImageLoader = CustomVolleyRequestQueue.getInstance(getApplicationContext()).getImageLoader();
mImageLoader.get(values[0], ImageLoader.getImageListener(mNetworkImageView, R.mipmap.ic_launcher_round, android.R.drawable.ic_menu_report_image));
Log.e("Image Published", values[0]);
mNetworkImageView.setImageUrl(values[0], mImageLoader);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
progressDialog.dismiss();
tv.setText(s);
}
}
OnBeaconServiceConnect:-
public void onBeaconServiceConnect() {
//Constructing a new Region object to be used for Ranging or Monitoring
region = new Region("myBeaons", Identifier.parse("23542266-18D1-4FE4-B4A1-23F8195B9D39"), null, null);
//Specifies a class that should be called each time the BeaconService sees or stops seeing a Region of beacons.
beaconManager.addMonitorNotifier(new MonitorNotifier() {
/*
This override method is runned when some beacon will come under the range of device.
*/
#Override
public void didEnterRegion(Region region) {
System.out.println("ENTER ------------------->");
try {
//Tells the BeaconService to start looking for beacons that match the passed Region object
// , and providing updates on the estimated mDistance every seconds while beacons in the Region
// are visible.
beaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
Log.e("Debug", "Step10");
}
/*
This override method is runned when beacon that comes in the range of device
,now been exited from the range of device.
*/
#Override
public void didExitRegion(Region region) {
System.out.println("EXIT----------------------->");
try {
//Tells the BeaconService to stop looking for beacons
// that match the passed Region object and providing mDistance
// information for them.
beaconManager.stopRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
Log.e("Debug", "Step11");
}
/*
This override method will Determine the state for the device , whether device is in range
of beacon or not , if yes then i = 1 and if no then i = 0
*/
#Override
public void didDetermineStateForRegion(int state, Region region) {
System.out.println("I have just switched from seeing/not seeing beacons: " + state);
}
});
//Specifies a class that should be called each time the BeaconService gets ranging data,
// which is nominally once per second when beacons are detected.
beaconManager.addRangeNotifier(new RangeNotifier() {
/*
This Override method tells us all the collections of beacons and their details that
are detected within the range by device
*/
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
// Checking if the Beacon inside the collection (ex. list) is there or not
// if Beacon is detected then size of collection is > 0
if (beacons.size() > 0) {
final ArrayList<ArrayList<String>> arrayList = new ArrayList<ArrayList<String>>();
BeaconManager.setRssiFilterImplClass(ArmaRssiFilter.class);
// Iterating through all Beacons from Collection of Beacons
ArrayList<Integer> arr = new ArrayList<Integer>();
int count = 0;
for (Beacon b : beacons) {
//RSSI
count += 1;
System.out.println(b.getBluetoothAddress()+" : "+b.getBluetoothName());
System.out.println("Count : " + count);
Integer rssi = Integer.valueOf(b.getRssi());
arr.add(rssi);
Integer maxRssi = Collections.max(arr);
for(Beacon b1 : beacons){
if(b1.getRssi() == maxRssi)
{
start = b1.getId1().toString();
maxid = start;
Log.e("Debug", "Step12");
System.out.println("uuid :"+func());
}
}
}
}
}
});
try {
//Tells the BeaconService to start looking for beacons that match the passed Region object.
beaconManager.startMonitoringBeaconsInRegion(region);
} catch (RemoteException e) {
}
}
#Override
public void onDestroy() {
super.onDestroy();
//Unbinds an Android Activity or Service to the BeaconService to avoid leak.
beaconManager.unbind(this);
finish();
}
The bid is set on the first go. Whenever I exit the app and reopen it again, the bid will not change at all. I have to clear the data of the app and re-run it to work properly.

Related

AltBeacon sometime cannot range beacons

I want my app track with beacon all the time
it seem work fine been a while when it start tracking
after that, didRangeBeaconsInRegion() has an empty beacons collection
Here my code
public void onCreate() {
super.onCreate();
Log.d(TAG, "create");
beaconManager = BeaconManager.getInstanceForApplication(this);
try {
beaconManager.getBeaconParsers().clear();
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
beaconManager.setBackgroundScanPeriod(1101l);
beaconManager.setBackgroundBetweenScanPeriod(1101l);
beaconManager.setForegroundBetweenScanPeriod(1101l);
beaconManager.updateScanPeriods();
} catch (RemoteException e) { }
backgroundPowerSaver = new BackgroundPowerSaver(this);
startBeaconRanging();
}
public void startBeaconRanging() {
courseId = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString(getString(R.string.course_id), "");
Log.d(TAG, "startBeaconRanging on courseId = " + courseId);
if (!courseId.equals("")) {
syncBeaconWithFirebase(courseId);
endTime = CourseSQLiteManager.getColumnById(getApplicationContext(), courseId, COURSE_ENDTIME);
regionBootstrap = new RegionBootstrap(this, new Region("ranged region", null, null, null));
}
}
public void stopBeaconRanging() {
if (regionBootstrap != null) {
regionBootstrap.disable();
try {
Log.d(TAG, "end");
courseId = "";
beaconManager.stopRangingBeaconsInRegion(getRegion());
beaconManager.removeAllRangeNotifiers();
} catch (RemoteException e) { }
}
}
#Override
public void didEnterRegion(Region region) {
Log.d(TAG, "enter");
try {
Region r = getRegion();
if(r == null) {
regionBootstrap = new RegionBootstrap(this, new Region("ranged region", null, null, null));
Log.d(TAG, "null");
}
if(r != null) {
beaconManager.startRangingBeaconsInRegion(r);
beaconManager.addRangeNotifier(this);
}
} catch (RemoteException e) { }
}
#Override
public void didExitRegion(Region region) {
try {
if(getRegion() != null) beaconManager.stopRangingBeaconsInRegion(getRegion());
} catch (RemoteException e) { }
}
#Override
public void didDetermineStateForRegion(int i, Region region) {
}
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if(beacons.size() > 0) {
Beacon beacon = beacons.iterator().next();
Log.d(TAG, beacon.getId2().toInt() + " " + beacon.getDistance() + " " + beacon.getRssi());
if(isAfterEndTime()) {
stopBeaconRanging();
}
}
}
EDIT: It happen like this both foreground and background. But If I kill my app and open it again, I can finds beacon but just a moment too.
EDIT2: isAfterEndTime is return false while it cannot finds any beacons. But the didExitRegion is triggered swap with didEnterRegion and it finds zero beacons
PS. I want to track with only one beacon at a time
PS.2 Sorry for my bad English. I'm not sure, are you get what I want to ask clearly or not?
A few things to check:
Make sure this code is not being triggered. I cannot see the definition of the method, but if it returns true, it will cause ranging to stop:
if(isAfterEndTime()) {
stopBeaconRanging();
}
Add a debug line in the didExitRegion to make sure it is not being called. (Since it also stops ranging.) As an aside, I don't think you need code that does this -- there is no efficiency cost to just continuing ranging if you aren't detecting beacons anyway.
Make sure this line of code is only executed once, as the RegionBootstrap is not designed to be created repeatedly:
regionBootstrap = new RegionBootstrap(this, new Region("ranged region", null, null, null));
Rather than repeatedly making a new RegionBootstrap object, just create one once at the beginning of your program. If you then want to change the monitored regions, you can do so with beaconManager.stopMonitoringBeaconsInRegion(region1); and beaconManager.startMonitoringBeaconsInRegion(region2);

iBeacons' background ranging with Altbeacon Library

I need to range beacons on the background using Altbeacons library(work properly on foreground mode)
On my android monitor the log never shows the message for the didRangeBeaconsInRegion method.
On the didEnterRegion, the messages are displayed correctly.
I tried the code below but no success, can any one guide me how to do it?
public class INBeaconApplication extends Application implements BootstrapNotifier, RangeNotifier {
private BeaconManager beaconManager;
private ArrayList<INBeacon> userBeaconArrayList;
private INBeaconUser inBeaconUser;
#Override
public void onCreate() {
super.onCreate();
Log.d("INBeacon", "Application created");
//BeaconManager and custom beaconParser layout
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().clear();
beaconManager.getBeaconParsers().add(new BeaconParser()
.setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
beaconManager.setRegionStatePeristenceEnabled(false);
//Set the BeacomManager background between scan periods
long period = 1000 * 30; //equal to 30 seconds
beaconManager.setBackgroundBetweenScanPeriod(period);
// wake up the app when a beacon is seen
Region region = new Region(Utils.REGION_ID, Identifier
.parse(Utils.INBEACON_UUID), null, null);
new RegionBootstrap(this, region);
new BackgroundPowerSaver(this);
}
boolean checkPermissionForRange(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return getApplicationContext().checkSelfPermission(
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED;
}
return true;
}
#Override
public void didEnterRegion(Region region) {
Log.d("INBeacon", "didEnterRegion");
Utils.sendNotification(this, "Test");
if (checkPermissionForRange()) return;
Log.d("INBeacon", "permissions ok");
try {
beaconManager.startRangingBeaconsInRegion(region);
Log.d("INBeacon","startRanging");
} catch (RemoteException e) {
Log.e("INBeacon",e.getMessage());
}
}
#Override
public void didExitRegion(Region region) {
Log.d("INBeacon", "didExitRegion");
try {
beaconManager.stopRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> collection, Region region) {
Log.d("INBeacon", "didRangeBeaconsInRegion");
ArrayList<Beacon> newBeacons = new ArrayList<>(collection);
.............code to do what i need with the beacons.....
}
It looks like the code simply needs to call:
beaconManager.setRangeNotifier(this);

How to parse iBeacon identifiers from Altbeacon's bootstrap and start application with them?

I'm trying to get the bootstrap to gather id2 and id3 from iBeacons and start an activity with them. The problem is that the application wouldn't start from the intent and I keep seeing D/BeaconService﹕ Calling ranging callback D/Callback﹕ attempting callback via intent: ComponentInfo{com.rp_ds.chequeplease/org.altbeacon.beacon.BeaconIntentProcessor}
Below is my code:
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "App started up");
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.setDebug(true);
// Add AltBeacons Parser for iBeacon
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
// wake up the app when any beacon is seen (you can specify specific id filers in the parameters below)
region = new Region("com.rp_ds.chequeplease.bootstrapRegion", Identifier.parse("F8EFB5C2-9FFF-47AE-8C8D-D23C417882D1"), null, null);
regionBootstrap = new RegionBootstrap(this, region);
backgroundPowerSaver = new BackgroundPowerSaver(this);
_appPrefs = new AppPreferences(this);
}
#Override
public void didDetermineStateForRegion(int arg0, Region arg1) {
// Don't care
}
#Override
public void didEnterRegion(Region arg0) {
Log.d(TAG, "Got a didEnterRegion call");
try {
beaconManager.startRangingBeaconsInRegion(arg0);
} catch (RemoteException e) {
e.printStackTrace();
}
// This call to disable will make it so the activity below only gets launched the first time a beacon is seen (until the next time the app is launched)
// if you want the Activity to launch every single time beacons come into view, remove this call.
}
#Override
public void didExitRegion(Region arg0) {
// Don't care
}
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
Log.d(TAG, "Got a didRangeBeaconsInRegion call");
for(Beacon beacon:beacons) {
if(null!=beacon.getId2()&&null!=beacon.getId3()) {
Intent intent = new Intent(this, MainActivity.class);
_appPrefs.setRestaurantID(beacon.getId2().toInt());
_appPrefs.setTableNumber(beacon.getId3().toInt());
// IMPORTANT: in the AndroidManifest.xml definition of this activity, you must set android:launchMode="singleInstance" or you will get two instances
// created when a user launches the activity manually and it gets launched from here.
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(intent);
Log.i(TAG,"Application started");
try {
beaconManager.stopRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
}
}
I do get a didEnterRegion call but there wasn't a didRangeBeaconsInRegion call. The beacons are also recognized.
D/BeaconParser﹕ This is a recognized beacon advertisement -- 0215 seen
D/BeaconIntentProcessor﹕ got an intent to process
D/RangingData﹕ parsing RangingData
D/RangingData﹕ parsing RangingData
D/BeaconIntentProcessor﹕ got ranging data
D/BeaconIntentProcessor﹕ but ranging notifier is null, so we're dropping it.
The range notifier needs to be set like this:
#Override
public void didEnterRegion(Region arg0) {
Log.d(TAG, "Got a didEnterRegion call");
try {
beaconManager.startRangingBeaconsInRegion(arg0);
beaconManager.setRangeNotifier(this);
} catch (RemoteException e) {
e.printStackTrace();
}
}
Make sure the containing class implements the RangeNotifier interface.

Android Estimote sdk is not able to scan other beacons than the estimote ones

I am trying to see beacons with the estimote sdk in android but with no luck!I can see all the estimote beacons but with all other beacons is not working (fobo beacons etc.) I am using the uuid for the fobo beacons inside the Region constructor and i can see in the logcat that the bluetooth can see the devices but estimode sdk is not collecting it as a beacon!Any ideas why this is happening? I m posting the code below:
private static final String FOBO_PROXIMITY_UUID = "00158800-587d-2206-d52b-fb6d6e2f0001";
private static final Region FOBOBEACONS = new Region("rid", FOBO_PROXIMITY_UUID , null, null);
public void BeaconManager(){
beaconManager = new com.estimote.sdk.BeaconManager(this);
beaconManager.setBackgroundScanPeriod(5000, 30000);
beaconManager.setForegroundScanPeriod(7000, 5000);
beaconManager.setRangingListener(new com.estimote.sdk.BeaconManager.RangingListener() {
#Override
public void onBeaconsDiscovered(final Region arg0, final List<Beacon> arg1) {
// TODO Auto-generated method stub
runOnUiThread(new Runnable() {
#Override
public void run() {
// Note that beacons reported here are already sorted by estimated
// distance between device and beacon.
int test=0;
if(arg1.size()<=0){
Toast.makeText(MainActivity.this, "No beacon found",
Toast.LENGTH_SHORT).show();
}else{
for (int i = 0; i < arg1.size(); i++) {
String beac=arg1.get(i).getProximityUUID();
Toast.makeText(MainActivity.this, "I found a beacon with UUID; "+beac,
Toast.LENGTH_SHORT).show();
}
}
// adapter.replaceWith(beacons);
}
});
}
});
connectToService();
}
private void connectToService() {
beaconManager.connect(new com.estimote.sdk.BeaconManager.ServiceReadyCallback() {
#Override
public void onServiceReady() {
try {
com.estimote.sdk.utils.L.enableDebugLogging(true);
beaconManager.startRanging(FOBOBEACONS);
} catch (RemoteException e) {
Toast.makeText(MainActivity.this, "Cannot start ranging, something terrible happened",
Toast.LENGTH_LONG).show();
}
}
});
}
This is Wojtek Borowicz, I'm a community evangelist at Estimote. Actually, Estimote SDK does not support Beacons from other vendors - that's why you cannot detect them.
Cheers.
Maybe check this link.. not tried it yet myself but plan to at some point.
https://github.com/AlvinBert
An Android source code of iBeacon SDK. without any limit on Android.
It can detect all iBeacons.

Implement barge-in for Android TTS

I am having difficulty figuring out how to resolve this issue, I am not sure if I am not setting up threads correctly or if it is even possible to resolve things properly.
This is an Android app that reads certain strings out as TTS (using the native Android TTS) at certain timings. During this TTS reading, the user should be able to barge-in with instructions such as "Stop" or "Pause." This recognition is done by using the iSpeech API.
Our current solution is to have the TTS running as a Thread that will output the proper strings. Once the user presses a button to begin the voice recognition (using an Intent), the app does voice recognition and handles it perfectly, but then TTS never again outputs anything. Logcat shows the following error:
11-28 02:18:57.072: W/TextToSpeech(16383): speak failed: not bound to TTS engine
I have thought about making the voice recognition a thread of its own that pauses the TTS, but the problem would then be that the timer controlling the TTS would become unsynced with what it should be.
Any advice or help would be appreciated.
Relevant code regarding the thread and the intent are below:
Thread
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Prevent device from sleeping mid build.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_build_order);
mPlayer = MediaPlayer.create(BuildOrderActivity.this, R.raw.bing);
params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,"stringId");
tts = new TextToSpeech(BuildOrderActivity.this, new TextToSpeech.OnInitListener() {
#SuppressWarnings("deprecation")
public void onInit(int status) {
if(status != TextToSpeech.ERROR)
{
tts.setLanguage(Locale.US);
tts.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {
public void onUtteranceCompleted(String utteranceId) {
mPlayer.start();
}
});
}
}
});
buttonStart = (Button) findViewById(R.id.buttonStartBuild);
buttonStart.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startBuild = new StartBuildRunnable();
Thread t = new Thread(startBuild);
t.start();
}
});
...//code continues oncreate setup for the view}
public class StartBuildRunnable implements Runnable {
public void run() {
double delay;
buildActions = parseBuildXMLAction();
buildTimes = parseBuildXMLTime();
say("Build has started");
delayForNextAction((getSeconds(buildTimes.get(0)) * 1000));
say(buildActions.get(0));
for (int i = 1; i < buildActions.size(); i++)
{
delay = calcDelayUntilNextAction(buildTimes.get(i - 1), buildTimes.get(i));
delayForNextAction((long) (delay * 1000));
say(buildActions.get(i));
//listViewBuildItems.setSelection(i);
}
say("Build has completed");
}
}
Intent
/**
* Fire an intent to start the speech recognition activity.
* #throws InvalidApiKeyException
*/
private void startRecognition() {
setupFreeFormDictation();
try {
recognizer.startRecord(new SpeechRecognizerEvent() {
#Override
public void onRecordingComplete() {
updateInfoMessage("Recording completed.");
}
#Override
public void onRecognitionComplete(SpeechResult result) {
Log.v(TAG, "Recognition complete");
//TODO: Once something is recognized, tie it to an action and continue recognizing.
// currently recognizes something in the grammar and then stops listening until
// the next button press.
if (result != null) {
Log.d(TAG, "Text Result:" + result.getText());
Log.d(TAG, "Text Conf:" + result.getConfidence());
updateInfoMessage("Result: " + result.getText() + "\n\nconfidence: " + result.getConfidence());
} else
Log.d(TAG, "Result is null...");
}
#Override
public void onRecordingCancelled() {
updateInfoMessage("Recording cancelled.");
}
#Override
public void onError(Exception exception) {
updateInfoMessage("ERROR: " + exception.getMessage());
exception.printStackTrace();
}
});
} catch (BusyException e) {
e.printStackTrace();
} catch (NoNetworkException e) {
e.printStackTrace();
}
}

Categories

Resources