Android Beacon Library Reference Application Help (didEnterRegion function) - ibeacon

My region is:
Region region = new Region("backgroundRegion", Identifier.parse("24DDF411-8CF1-440C87CD-E368DAF9C93E"), null, null);
When I start the program I get this message:
06-26 18:03:21.061 7394-7394/? D/BeaconReferenceApp: setting up background monitoring for beacons and power saving
But it doesn't enter in any didEnterRegion function
So, I removed this line: backgroundPowerSaver = new BackgroundPowerSaver(this);
And change scanning times, as it follows:
beaconManager.setBackgroundScanPeriod(1100l);
beaconManager.setBackgroundBetweenScanPeriod(10000l-1100l);
I checked my Beacon UUID and they are 24DDF411-8CF1-440C87CD-E368DAF9C93E
So what is wrong? Why the app doesn't go to the didEnterRegion function?
I already made it work to work with other than AltBeacons... (ranging function works ok!)
My final goal is to get current time when a beacon is discovered...

A few possibilities:
If you are already in the beacon region, you won't get a second callback until the beacon disappears (turn it off for 30 seconds or so, then turn it back on while the app is running.) Alternatively, you can look for a call do didDetermineStateForRegion which is always called when your app starts up, with a flag that tells you if you are inside or outside.
Make sure you have granted runtime permissions to location.
Make sure location is turned on for your phone in settings.
Make sure the beacon is transmitting that identifier using the Locate app https://play.google.com/store/apps/details?id=com.radiusnetworks.locate&hl=en
Make sure you have the proper BeaconParser configured. The question is tagged Eddystone, but shows an iBeacon or AltBeacon-style UUID as the first identifier. Do you have a custom beacon parser configured? What beacon type are you trying to detect?

Related

How to detect android watch is worn or not on AW2.0

Android wear 2.0 screen can be automatically locked right after it is taken off
and the heart rate app / watch face would not work when it is not worn.
I am wondering is there any way to get current wear worn state without starting a service to listen to wear activity?
I tried to get the heart rate sensor accuracy, but I don't think it is a good way because I can not always get the right result in this way immediately.
Is there any system or gms API to get a current worn state synchronously?
On watches with an off-body sensor (which lock immediately when not worn), you can check for the existence of the wakeup sensor TYPE_LOW_LATENCY_OFF_BODY_DETECT. This is only a public API in O+, but you can just use the actual value for N MR1 and below.
SensorManager sensorManager =
(SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
boolean hasSensor = sensorManger.getDefaultSensor(34, true /* wakeup */) != null;
On watches without an off-body sensor (which don't lock immediately), your best bet is probably some sort of activity recognition, though there don't seem to be any public off-body activities that can be detected by Google APIs (see here).

Adobe Analytics - Force a session/userID refresh

We have a website that can be viwed from a kiosk in a shop.
When the inactivity is above 2 minutes, the site returns to the home.
Anyone knows how to refresh the session when this appens?
It could also serve make a refresh of the user id, but I don't know how it works.
I'm going to assume you are talking about Adobe Analytics javascript library and not the Android/iOS SDK, based on your tagging and lack of mention of it. If your kiosk is in fact using Android or iOS SDK, then please comment and I can update with instructions for that.
Adobe Analytics javascript library does not currently offer a direct method to force refresh an Adobe Analytics session/userID. However, you can effectively do it by explicitly setting s.visitorID yourself, which will override the default generated by the library.
So, when you want to start a new session, you can pop s.visitorID with for example the current timestamp:
s.visitorID = (new Date()).getTime().toString();
Or maybe you already have a "session" id you generate that you can use, instead.
Note: with this method, you must set s.visitorID (with the same value) for every hit for the duration of your session. So in practice, you would really do something more along the lines of generate the new value at start of session, put the value in a cookie, and put s.visitorID in s_doPlugin but it reads the cookie value.
Note: This will effectively make your visits and visitors metrics the same. Which is to be expected with a publicly shared device, but just mentioning it in case it comes up later.
pseudocode:
function startNewSession() {
// use whatever cookie writing utility you have to
// set a cookie named visitorID set to the generated
// value. In practice, the expiration doesn't really
// matter as long as it's something longer than
// your average session. Just setting it to default
// session expiration should be okay
var visitorID = (new Date()).getTime().toString();
setCookie('visitorID',visitorID);
}
// in your existing logic that times out returning
// home after 2 minutes of inactivity, call the function
// to generate a new id
startNewSession();
// this is AA's s_doPlugins callback function. This may look
// slightly different, maybe defined as s_doPlugins and then assigned
// to s.doPlugins, depending on what AA lib version you are using.
// This is AA's callback function that gets called whenever
// an s.t or s.tl call is made
s.usePlugins=true;
s.doPlugins=function(s) {
// make sure visitorID variable is addedto linkTrackVars
// so it gets 'registered' for s.tl calls.
s.linkTrackVars='visitorID';
// explicitly set the visitorID with the cookie, using
// whatever cookie reading utility you have.
s.visitorID=readCookie('visitorID');
}

Non helpfull error message Calabash with page objects pattern

I'm currently using Calabash framework to automate functional testing for a native Android and IOS application. During my time studying it, I stumbled upon this example project from Xamarin that uses page objects design pattern which I find to be much better to organize the code in a Selenium fashion.
I have made a few adjustments to the original project, adding a file called page_utils.rb in the support directory of the calabash project structure. This file has this method:
def change_page(next_page)
sleep 2
puts "current page is #{current_page_name} changing to #{next_page}"
#current_page = page(next_page).await(PAGE_TRANSITION_PARAMETERS)
sleep 1
capture_screenshot
#current_page.assert_info_present
end
So in my custom steps implementation, when I want to change the page, I trigger the event that changes the page in the UI and update the reference for Calabash calling this method, in example:
#current_page.click_to_home_page
change_page(HomePage)
PAGE_TRANSITION_PARAMETERS is a hash with parameters such as timeout:
PAGE_TRANSITION_PARAMETERS = {
timeout: 10,
screenshot_on_error: true
}
Just so happens to be that whenever I have a timeout waiting for any element in any screen during a test run, I get a generic error message such as:
Timeout waiting for elements: * id:'btn_ok' (Calabash::Android::WaitHelpers::WaitError)
./features/support/utils/page_utils.rb:14:in `change_page'
./features/step_definitions/login_steps.rb:49:in `/^I enter my valid credentials$/'
features/04_support_and_settings.feature:9:in `And I enter my valid credentials'
btn_ok is the id defined for the trait of the first screen in my application, I don't understand why this keeps popping up even in steps ahead of that screen, masking the real problem.
Can anyone help getting rid of this annoyance? Makes really hard debugging test failures, specially on the test cloud.
welcome to Calabash!
As you might be aware, you'll get a Timeout waiting for elements: exception when you attempt to query/wait for an element which can't be found on the screen. When you call page.await(opts), it is actually calling wait_for_elements_exist([trait], opts), which means in your case that after 10 seconds of waiting, the view with id btn_ok can't be found on the screen.
What is assert_info_present ? Does it call wait_for_element_exists or something similar? More importantly, what method is actually being called in page_utils.rb:14 ?
And does your app actually return to the home screen when you invoke click_to_home_page ?
Unfortunately it's difficult to diagnose the issue without some more info, but I'll throw out a few suggestions:
My first guess without seeing your application or your step definitions is that #current_page.click_to_home_page is taking longer than 10 seconds to actually bring the home page back. If that's the case, simply try increasing the timeout (or remove it altogether, since the default is 30 seconds. See source).
My second guess is that the element with id btn_ok is not actually visible on screen when your app returns to the home screen. If that's the case, you could try changing the trait definition from * id:'btn_ok' to all * id:'btn_ok' (the all operator will include views that aren't actually visible on screen). Again, I have no idea what your app looks like so it's hard to say.
My third guess is it's something related to assert_info_present, but it's hard to say without seeing the step defs.
On an unrelated note, I apologize if our sample code is a bit outdated, but at the time of writing we generally don't encourage the use of #current_page to keep track of a page. Calabash was written in a more or less stateless manner and we generally encourage step definitions to avoid using state wherever possible.
Hope this helps! Best of luck.

OS X Today Widget - How to detect in NCWidgetProviding.widgetPerformUpdateWithCompletionHandler if content has changed?

widgetPerformUpdateWithCompletionHandler() gives us the possibility to let the Notification Center know if the content of a Today Extension has changed. For example:
func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)!) {
// Refresh the widget's contents in preparation for a snapshot.
// Call the completion handler block after the widget's contents have been
// refreshed. Pass NCUpdateResultNoData to indicate that nothing has changed
// or NCUpdateResultNewData to indicate that there is new data since the
// last invocation of this method.
if(has_new_data()) { // There was an update
completionHandler(.NewData)
}
else { // nothing changed!
completionHandler(.NoData)
}
}
But how would we know if the content has changed? On every snapshot the widget is instantiated from scratch. It is a complete new process with new PID. So you can not store any property in your instance. How would one compare the current widget content with the content of the previous snapshot?
I used Core Data to store the current content for later comparison. This is obvious and works. But then another problem crashes in: What if there is no previous snapshot? Let's say the user removed the widget just to re-add it again. Or the user rebooted. There might be more reasons why there is no previous snapshot that I can not think of now. Either way - there still is content stored in Core Data. If the comparison between this old content and the current content detects there are no changes and I return .NoData the widget would end up empty because the Notification Center would not redraw the content.
You might wonder why It is so important to me to call the completionHandler with a correct state and not simply always return .NewData. That's because I am experiencing a little flicker when there is no change and still return .NewData. I have some images in my widget and when redrawing the widget the whole content gets invisible for a millisecond - long enough to notice.
Is there something I am missing? It seems strange to me that Apple provides a way to give us the option to respond with different states but then makes it impossible to detect which state we should respond.
In theory you would use this to check whether there was any new content since the last call, and pass back the appropriate value. I suppose in theory it might be the same instance of the view controller on more than one call, but that's clearly not how things work right now. Checking whether content has changed depends on the nature of the app and the extension. Since you're using a shared Core Data store to share data, you might do something like:
Any time the app changes data, save the current date in shared user defaults.
Any time the today extension reads data, save the current date in shared user defaults.
When widgetPerformUpdateWithCompletionHandler is called, look up both of those dates. If the data has changed more recently than the last time the extension read that data, return NCUpdateResultNewData. If not, return NCUpdateResultNoData.
You could also save these dates in the metadata on the persistent store instead of in shared user defaults. If it was the same view controller each time, you might keep the value from step 2 in memory instead of saving it to a file. But again that's not how it works now, and it's not clear when or if that will change.
Apps that save data in some other way might need to use different checks, the details of which would depend on how their app and extension worked.
In practice with iOS 8.2 it really doesn't matter because the extension environment doesn't seem to care what value you send back. I tried returning NCUpdateResultNewData and compared it to returning NCUpdateResultNoData every time. There was absolutely no effect on the life cycle of the today extension view controller or its views.
As an aside, it's not always a different process. I tried putting this line in the today extension's viewDidLoad:
NSLog(#"viewDidLoad pid=%d self=%#", getpid(), self);
Then I ran the today extension, scrolled up and down in the notification center a couple of times, closed the notification center, reopened it, and got the following:
2015-03-17 15:19:01.203 DemoToday[3484:903442] viewDidLoad pid=3484 self=<TodayViewController: 0x12d508cc0>
2015-03-17 15:19:14.441 DemoToday[3484:903442] viewDidLoad pid=3484 self=<TodayViewController: 0x12d50ade0>
2015-03-17 15:19:23.784 DemoToday[3484:903442] viewDidLoad pid=3484 self=<TodayViewController: 0x12d619c40>
2015-03-17 15:19:29.015 DemoToday[3484:903442] viewDidLoad pid=3484 self=<TodayViewController: 0x12d50abe0>
Although it's a different instance of the view controller each time, it's the same pid in each of these cases.
You can use any storage API ( Core Data, NSCoding, SQLite ) as long as you enable data sharing with your host app.
https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html
Even if the user removes the widget or reboots the device, the data will be stored on your shared container. Whenever iOS launches your widget, you will be able to read and write the same shared container that you have previously used.
Be aware that your host app and your widget may read or write concurrently so you have to coordinate any reading and writing operation.
The simplest way to do this is to cache your current widgets state in user defaults. Then when the widget loads (in viewDidLoad) fetch your cached data from user defaults and set it as a property on your widget view controller.
Then when widgetPerformUpdateWithCompletionHandler is called you have your previous updated and you can decide if you need to do a network request of if your data is fresh enough. If you do a web request you can then compare it to your cache to determine if you have new data or no update.
No need to persist any data in UserDefaults or even Core Storage. Keep it simple: Just declare the variable(s) you use to store any calculated contents or data you use to check whether something changed to be static. Since the widget runs in the same process (as shown here) the static data will be available the next time your widget is activated.
static NSDate *lastDate;
- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler {
NSDate * currentDate = [NSDate date];
if (!lastDate ||
[[NSCalendar currentCalendar]compareDate:lastDate toDate:currentDate toUnitGranularity:NSCalendarUnitDay] != NSOrderedSame) {
// Date changed
lastDate = currentDate;
... do whatever needs to be done ...
completionHandler(NCUpdateResultNewData);
} else {
completionHandler(NCUpdateResultNoData);
}
}

CBPeripheral name in iOS6

I'm using Apple's BLTE Tansfer to simulate a heart rate monitor.
Also I have an app that receives the simulated data.
I have question a the use of CBPeripheral:
I want to control the peripheral's name.
First I've tried to add the GAP Service and name characteristic using:
[CBUUID UUIDWithString:CBUUIDGenericAccessProfileString]
[CBUUID UUIDWithString:CBUUIDDeviceNameString]
but Xcode tells me it is not recommended.
It also seems that the service is already included (when watching didDiscoverServices on the receiver side).
How can I access the name property (I want to transmit it to the receiver)?
You don't need to add new services just set up the advertisement in the following way:
NSDictionary *advData =
#{CBAdvertisementDataLocalNameKey:#"<your desired name>",
CBAdvertisementDataServiceUUIDsKey:#[[CBUUID UUIDWithString:#"180D"]]};
[peripheralManager startAdvertising:advData];

Resources