petermetz / cordova-plugin-ibeacon

An iBeacon plugin for Phonegap / Cordova 3.x and upwards. Supports both iOS and Android (contributions are welcome)
Apache License 2.0
726 stars 373 forks source link

IOS background problem #123

Open Dionysios opened 9 years ago

Dionysios commented 9 years ago

Hi, I have a small project which requires ibeacons ranging in the foreground and monitoring with local notifications on the background. The plugin works great on Android but on IOS once I put the app on the background nothing happens. I looked the issue #53 but no luck. Here is the code. Any help is appreciated. Thanks in advance!

app.startScanForBeacons = function() { console.log('startScanForBeacons');

var delegate = new locationManager.Delegate();

delegate.didStartMonitoringForRegion = function(pluginResult){ console.log('Call monitoring'); app.didBeaconsInRegion(pluginResult); };

// Called when monitoring and the state of a region changes. // (Not used in this example, included as a reference.) delegate.didDetermineStateForRegion = function(pluginResult){ //console.log('didDetermineStateForRegion: ' + JSON.stringify(pluginResult)) };

delegate.didStartRangingBeaconsInRegion = function(pluginResult){ console.log('didDetermineStateForRegion: ' + JSON.stringify(pluginResult)) };

delegate.didRangeBeaconsInRegion = function(pluginResult){ console.log('didDetermineStateForRegion: ' + JSON.stringify(pluginResult)) // app.didBeaconsInRegion(pluginResult); };

// Set the delegare object to use. locationManager.setDelegate(delegate) // Request permission from user to access location info. // This is needed on iOS 8. locationManager.requestAlwaysAuthorization();

// Start monitoring and ranging our beacons. for (var r in app.beaconRegions) { var region = app.beaconRegions[r]

var beaconRegion = new locationManager.BeaconRegion( region.id, region.uuid, region.major, region.minor)

// Start monitoring.
locationManager.startMonitoringForRegion(beaconRegion)
.fail(console.error)
.done()

// Start ranging.
locationManager.startRangingBeaconsInRegion(beaconRegion)
.fail(console.error)
.done()

} } // Display pages depending of which beacon is close. app.didBeaconsInRegion = function(pluginResult) {

sebastianh84 commented 9 years ago

i have the same problem

zefman commented 9 years ago

Any solutions? I would love to use this plugin for a new project I have coming up but if this isn't working its a bit of a deal breaker for me.

sebastianh84 commented 9 years ago

i got a notification when app is colsed today but still testing I have de.appplant.cordova.plugin.local-notification and com.unarin.cordova.beacon installed looks like this var app = (function() { // Application object. var app = {};

// Specify your beacon UUIDs here.
var regions =
[
    // Estimote Beacon factory UUID.
    {uuid:'xxx'}
];

// Dictionary of beacons.
var beacons = {};

// Timer that displays list of beacons.
var updateTimer = null;

app.initialize = function()
{
    document.addEventListener('deviceready', onDeviceReady, false);
};

function onDeviceReady()
{
    // Specify a shortcut for the location manager holding the iBeacon functions.
    window.locationManager = cordova.plugins.locationManager;

    // Start tracking beacons!
    startMonitoring();

    // Display refresh timer.
    //updateTimer = setInterval(displayBeaconList, 500);
}

function startMonitoring()
{

    window.plugin.notification.local.cancelAll();
    //window.plugin.notification.local.add({ message: 'startScanForBeacons' });

    var createLocalNotification = function (message) {
        window.plugin.notification.local.add({
            title:   'iBeacon',
            message: message
        });
    };

    // The delegate object holds the iBeacon callback functions
    // specified below.
    var delegate = new locationManager.Delegate();

    // Called continuously when ranging beacons.
    /*delegate.didRangeBeaconsInRegion = function(pluginResult)
    {
        //console.log('didRangeBeaconsInRegion: ' + JSON.stringify(pluginResult))
        for (var i in pluginResult.beacons)
        {
            // Insert beacon into table of found beacons.
            var beacon = pluginResult.beacons[i];
            beacon.timeStamp = Date.now();
            var key = beacon.uuid + ':' + beacon.major + ':' + beacon.minor;
            beacons[key] = beacon;
        }
    };*/

    // Called when starting to monitor a region.
    // (Not used in this example, included as a reference.)
    delegate.didStartMonitoringForRegion = function(pluginResult)
    {
        //createLocalNotification('[DOM] didStartMonitoringForRegion: ' + JSON.stringify(pluginResult));
        //console.log('didStartMonitoringForRegion:' + JSON.stringify(pluginResult))
    };

    // Called when monitoring and the state of a region changes.
    // (Not used in this example, included as a reference.)
    delegate.didDetermineStateForRegion = function(pluginResult)
    {
        //createLocalNotification('didDetermineStateForRegion: ' + JSON.stringify(pluginResult));
        //alert('didDetermineStateForRegion: ' + JSON.stringify(pluginResult))
    };

    delegate.didExitRegion = function(pluginResult) {
        //createLocalNotification('didExitRegion: ' + JSON.stringify(pluginResult));
    };

    delegate.didEnterRegion = function(pluginResult) {
        createLocalNotification('didEnterRegion: ' + JSON.stringify(pluginResult))

    };

    // Set the delegate object to use.
    locationManager.setDelegate(delegate);

    // Request permission from user to access location info.
    // This is needed on iOS 8.
    locationManager.requestAlwaysAuthorization();

    // Start monitoring and ranging beacons.
    //for (var i in regions)
    //{

    var uuid = 'xxx';
    var identifier = 'Startbeacon';
    var major= 'xxx';
    var minor = 'xxx';

        var beaconRegion = new locationManager.BeaconRegion(uuid,identifier,major,minor);

        // Start ranging.
        /*locationManager.startRangingBeaconsInRegion(beaconRegion)
            .fail(console.error)
            .done();
        */
        // Start monitoring.
        // (Not used in this example, included as a reference.)
        locationManager.startMonitoringForRegion(beaconRegion)
            .fail(console.error)
            .done();
    //}
}

function displayBeaconList()
{
    // Clear beacon list.
    $('#found-beacons').empty();

    var timeNow = Date.now();

    // Update beacon list.
    $.each(beacons, function(key, beacon)
    {
        // Only show beacons that are updated during the last 60 seconds.
        if (beacon.timeStamp + 60000 > timeNow)
        {
            // Map the RSSI value to a width in percent for the indicator.
            var rssiWidth = 1; // Used when RSSI is zero or greater.
            if (beacon.rssi < -100) { rssiWidth = 100; }
            else if (beacon.rssi < 0) { rssiWidth = 100 + beacon.rssi; }

            // Create tag to display beacon data.
            var element = $(
                '<li>'
                +   '<strong>UUID: ' + beacon.uuid + '</strong><br />'
                +   'Major: ' + beacon.major + '<br />'
                +   'Minor: ' + beacon.minor + '<br />'
                +   'Proximity: ' + beacon.proximity + '<br />'
                +   'RSSI: ' + beacon.rssi + '<br />'
                +   '<div style="background:rgb(255,128,64);height:20px;width:'
                +       rssiWidth + '%;"></div>'
                + '</li>'
            );

            $('#found-beacons').append(element);
        }
    });
}

return app;

})();

app.initialize();

Dionysios commented 9 years ago

I added these lines var notifyEntryStateOnDisplay = true; var beaconRegion = new cordova.plugins.locationManager.BeaconRegion(identifier, uuid, major, minor, notifyEntryStateOnDisplay);

and change testing device from an ipad mini to an iphone 5 and it started working for me. If you still have problems go through #53

//Dionysios

sebastianh84 commented 9 years ago

Hi, i have some questions:

  1. is it possible do notify only if the app is closed or runs in background?
  2. I want to notify the user only one time ('please open the app') if he enters a region of a single beacon the first time. If the app is running he should not be notified.
  3. How can i check the distance to the beacon if the app runs in background in didEnterRegion function, so that i can say if entered a beaconregion and the distance to the beacon is closer than 4meter, createLocalNotification

like

delegate.didEnterRegion = function(pluginResult) { if (app runs in background mode && beacon.distance < 4meter && userisnotalreadynotified == false){ createLocalNotification('didEnterRegion: ' + JSON.stringify(pluginResult))

   var userisnotalreadynotified = true

} };

does someone maybe have a codesnippet for that?

greez & thx 4 help Sebastian

0x1ad2 commented 8 years ago

Setting up the iBeacon regions like this didn't change a thing

new cordova.plugins.locationManager.BeaconRegion(identifier, uuid, major, minor, true);