deckameron / Ti.Android.Geofence

A Geofence solution for Appcelerator Titanium Android
Other
17 stars 5 forks source link

hint for receiving events when app is closed #5

Closed adegreiff closed 5 years ago

adegreiff commented 5 years ago

hi douglas, thanks for this module and happy new year to you.

you say in the description "This module works when the app is in foreground, background, closed, after phone restart,..." but down in the events part you say "These events can only be monitored when your app is in foreground or in background. They will never fire when your app is closed because the instance of your application does not exist".

can you give me a hint how i can receive the events when the app is closed or has not started after last phone reboot? foreground and background are already working fine but receiving enter events when app is not running is very essential for us.

thanks for your help.

kind regards alexander

deckameron commented 5 years ago

Hi @adegreiff , happy new year to you too!

I'd be happy to assist you with this. Could you please describe a little more what is your need (if it is permitted) so that I can make the necessary changes on the module, or suggest you a solution that will suit your application.

I understand that you need to monitor the events when the app instance does not exist. But, what exactly will you app need to do when this events fire? Will it need to change any UI element?

I am thinking that maybe, you need to combine this module with a background service and with nc.bootcompleted to guarantee that your service gets started again. Anyway, this is just conjecture. I will need more information in order to answer better. :)

My best regards!

adegreiff commented 5 years ago

thanks for your reply and help.

this is my scenario: after the app received an event like ENTERED it needs to check some preconditions like "is the user already checked in to the site related to this geofence" and if not, then show the user a notification e.g. "would you like to check in here".

i was under the impression that your module registeres the geofences with google playservices and playservices handle the geofences centrally (even after reboot) and trigger the app with an event.

btw. when the app is running, my eventlistener sees the geofence events but no notification is shown even though the config is identical to your example app. is there a change i need to make for the notification to show up?

thanks alexander

deckameron commented 5 years ago

I see! It will not be possible using only this module. You will need to use a service! You need to combine this module with a background service and with nc.bootcompleted to guarantee that your service gets started again after restart!

I will create a sample project and attach here as soon as possible.

i was under the impression that your module registeres the geofences with google playservices and playservices handle the geofences centrally (even after reboot) and trigger the app with an event.

It does! Is the OS that handles the fence control.

btw. when the app is running, my eventlistener sees the geofence events but no notification is shown even though the config is identical to your example app. is there a change i need to make for the notification to show up?

This is a bug! It should be showing the notifications.

prashantsaini1 commented 5 years ago

@deckameron I believe @adegreiff is using the similar environment as I am as we both are not getting the notifications. Point to note that we both are getting geofence events properly in background/foreground states, but we can't ensure if geofence working fine in killed state. I would not mind if device was rebooted for now. But getting notifications in killed state is more important than anything else for now as it's making module less useful on latest environment setups. Let me know if you need any assistance I can provide here.

@adegreiff I believe this is the same issue as I have reported here : https://github.com/deckameron/Ti.Android.Geofence/issues/4

gurudey commented 5 years ago

Killed state: no push. Background state: CANNOT FIRE (ENTER, EXIT OR DWELL) EVENT IN BACKGROUND. APPLICATION IS NULL, BECAUSE IT IS CLOSED! Foreground state: OK

deckameron commented 5 years ago

I have been banging my head against the wall with this issue. But today, I found this:

"GeoFence only get triggers if any app in the phone is fetching the location for some x duration. If you test the GeoFence sample app provided by google then you can see that the app works only when you open the Google maps application, its because Google Maps is the only app in the device that requests locations passively.

For Prove you can clone GeoFence sample and the LocationUpdateForGroundService sample from this below link https://github.com/googlesamples/android-play-location Run both of them GeoFence and LocationUpdateForGroundService at the same time, You will notice by changing the lat and long from the emulator that now you don't need to open Google maps any more because now there is another app which is requesting location."

Are you guys using Genymotion ou a real device? If so, please open Google Maps and check if the notification appears. It is important to know that on Android 8 and 9 the geofencing has a latency of 2-3 minutes.

prashantsaini1 commented 5 years ago

I believe I have noted this point long before even when I came to know this module and in all my tests I ran the titanium app in background for more than 30 minutes while continuously travelling in same geofence areas and with Google Maps app open in foreground to make sure my locations are triggered. Another point is that in real scenario, Google Maps will hardly be opened and hence making the module less useful even.

deckameron commented 5 years ago

Another point is that in real scenario, Google Maps will hardly be opened and hence making the module less useful even.

I know that! I just asked you to test with Maps opened in order to try to debug the problem. :-)

deckameron commented 5 years ago

Hi @adegreiff ,

I have implemented something that will help you on your project. No you have the possibility to pass a javascript code as service that will be executed on every geofence event. I am just finishing uploading the code. Please let me know if it solved your problem.

adegreiff commented 5 years ago

hi @deckameron, thanks for the info, sounds very promising. i will try this at my earliest possibility. do you have a sample for the service.js and how to call it? i guess that i do not need to set it up like this:

var intent = Titanium.Android.createServiceIntent({ url: 'service.js' }); intent.putExtra('interval', MINUTES * 60 * 1000); Titanium.Android.startService(intent); regards alexander

deckameron commented 5 years ago

Hi @adegreiff, you don't need to set it like this. You will do it like this:

If you want to execute a javascript code whenever the ENTERED, EXIT or DWELL events get fired. This is how:

1 ) Create a file name myService.js and write your backgroundService code. Place it in Resources folder.

//EXAMPLE
Ti.API.info('IT WORKED! It is a service');
var geofence = require("ti.android.geofence");

var geoTriggers = geofence.getLastestFiredGeofenceTransitionData();

var gLength = geoTriggers.fences.length;
for (var i=0; i < gLength; i++) {
    if(geoTriggers.fences[i].id == "huda_metro" && geoTriggers.event == geofence.ENTERED){
        geofence.fireNotification();
    }
};

2 ) Add the tag services to you android tag on tiapp.xml, like below:

<android xmlns:android="http://schemas.android.com/apk/res/android">
    <manifest>
     <!-- YOUR MANIFEST CODES HERE -->
    </manifest>
    <services>
        <service type="interval" url="myService.js"/>
    </services>
</android>

3) Compile the project

Before moving on and start using your service you will need to re-compile your project. After recompiling your project, open your "YOUR_PROJECTFOLDER"/build/android/AndroidManifest.xml. Look for your service name and you will find its full name, something like "com.myproject.geofence.myServiveService"_. This is important as Titanium generates this name. To learn more about Android Services please read the documentation here.

4) Add the service key to addGeofences method

geofence.addGeofences({
    clearExistingFences : false,
    fences : ["YOUR_FENCES"],
    service : "com.myproject.geofence.myServiveService" //THIS IS IT!
});

You can check out this test project.

adegreiff commented 5 years ago

thanks for the info. i was able to give it a try. in the service js i am getting this error:

` //bglocationservice.js var geofence = require('ti.android.geofence'); var geoTriggers = geofence.getLastestFiredGeofenceTransitionData();

[ERROR] : TiExceptionHandler: var geoTriggers = geofence.getLastestFiredGeofenceTransitionData(); [ERROR] : TiExceptionHandler: ^ [ERROR] : TiExceptionHandler: Error: Attempt to invoke virtual method 'java.lang.Object[] java.util.ArrayList.toArray()' on a null object reference `

otherwise i was able to add the geofences to the service. will continue to make it work and triggering the first events.

deckameron commented 5 years ago

@adegreiff try this build please!

adegreiff commented 5 years ago

@deckameron thanks for 1.06 but as soon as i add geofences the app is not responding anymore (ANR). the geofence.addGeofences({)) is taken from your example with other latitide longitude. will keep trying.

deckameron commented 5 years ago

I see! Could you provide me with more info about this error, please? I am trying to reproduce it but I am not getting the error.