Best way to intercept events like cordova resume and pause in ionic

Hi,

I need to intercept events like pause (in order to save application data to local storage) and restore it (on resume events) in order to keep my application running as sometimes the application restarts without any reason…
What will be the best way to do that and where can I put the appropriate code ?
Regards,
Sylvain

I don’t know if this is the “best” place. I have a “main” controller that resides on the <body>. In that controller, I simply listen for the document events.

    document.addEventListener("resume", function() {

        if($state.current.name.indexOf('main') !== -1 ) {

            $state.go('main.home');

            $scope.appCtrl.resetMember();

            // Close the loading indicator just in case it's still showing
            $scope.hideLoadingIndicator();

        }

    }, false);

    document.addEventListener("pause", function() {

        if($state.current.name.indexOf('main') !== -1 ) {

            $state.go('main.home');

            $scope.appCtrl.resetMember();

            // Close the loading indicator just in case it's still showing
            $scope.hideLoadingIndicator();

        }

    }, false);

I think that the best way to doit is creating a service that broadcast the resume, pause, online, etc events to their listeners.

App.factory('Device', ['$document', '$rootScope', function($document, $rootScope) {
  ...some other stuff...
  $document.addEventListener('resume', function() {
    $rootScope.$broadcast('onResume');
  });
  $document.addEventListener('pause', function() {
    $rootScope.$broadcast('onPause');
  });
...etc
}]);

and on your controller listen to the events with $scope.$on(‘onResume’, function() { do something });
always remember to remove those listener when you leave the controller!

BTW I didn’t test this code :smiley:

I put these types of listeners in app.js in a run block. If I want to do something elsewhere with them, then I broadcast an event as shown above.

I have tried the below code, but pause and resume function executes only once when app loads. However when app pauses or restarts I do see log like ‘Handle the pause’ and ‘Resuming the App’ but processPause() and processResume() never executes.

Please help!!!

 .run(function($ionicPlatform, $rootScope, SQLService) {
    	$ionicPlatform.ready(function() {	
    		document.addEventListener("deviceready", onDeviceReady, false);
    	});
    	
    	function onDeviceReady(){
    		//Add Pause event listener for autolock
    		window.addEventListener("pause", SQLService.processPause()  , false);
    
    		//Add Resume event listener for autolock
    		window.addEventListener("resume", SQLService.processResume(), false);
    		
    		SQLService.startApp();
    	};
    })

I’ve been able to get this to work, but code that executes during a pause does not seem to be able to do much (like save data via $http):

.run(function ($ionicPlatform, $rootScope) {

    $ionicPlatform.ready(function () {
        document.addEventListener("deviceready", onDeviceReady, false);
    });
    function onDeviceReady() {
        console.log('run() -> onDeviceReady');
        document.addEventListener("pause", function (event) {
            $rootScope.$broadcast('cordovaPauseEvent');
            console.log('run() -> cordovaPauseEvent');
        });
        document.addEventListener("resume", function (event) {
            $rootScope.$broadcast('cordovaResumeEvent');
            console.log('run() -> cordovaResumeEvent');
        });
    }

}

1 Like

From Cordova documentation:

iOS Quirks
In the pause handler, any calls to the Cordova API or to native plugins that go through Objective-C do not work, along with any interactive calls, such as alerts or console.log(). They are only processed when the app resumes, on the next run loop.

This is the reason why some things won’t work - like using SQLite etc.

So anyone have solution for this guy?

@francoaa, Yeah, the code doesn’t work :smile:

Here is a factory example using corrected syntax. Note the use of JQLite’s bind syntax.

angular.module('myApp').factory('broadcast', function ($rootScope, $document) {
    var _events = {
        onPause: 'onPause',
        onResume: 'onResume'
    };
    $document.bind('resume', function () {
        _publish(_events.onResume, null);
    });
    $document.bind('pause', function () {
        _publish(_events.onPause, null);
    });

    function _publish(eventName, data) {
        $rootScope.$broadcast(eventName, data)
    }
    return {
        events: _events
    }
});

Then subscribe where needed.

$scope.$on(broadcast.events.onPause, function (event) {
    //TODO: Do something
});
$scope.$on(broadcast.events.onResume, function (event) {
    //TODO: Do something
});

I prefer the use of $document over simply document.

I also use the events object to prevent magic numbers and to prevent fat fingering text constants (intellisense).

If its just a one time thing in a specific controller you can also do something as simple as this:

var destroy = $ionicPlatform.on('resume', function(event) {
  // check event, do some database work, etc.
});

$scope.$on('$destroy', function(event) {
  destroy(); // i.e. removes itself when context destroyed
});
1 Like

The same thing i have implemented in my, I works great in Android.

But in ios the event is not getting fired only how do i get this issue solved.

This is not what I am seeing. With the following code, “pausing…” is indeed shown in the console after the home button is pressed (ios simulator). Alert does not work here, however.

$ionicPlatform.on("pause", function(event) { console.log("pausing..."); });