{ "id": "124125", "key": "TIMOB-16066", "fields": { "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "20115", "name": "Release 7.3.0", "archived": false, "released": true, "releaseDate": "2018-08-17" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2018-06-06T01:31:04.000+0000", "created": "2013-12-21T20:36:49.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "android", "background", "demo_app", "exalture", "foreground", "services" ], "versions": [], "issuelinks": [ { "id": "56473", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "171536", "key": "TIMOB-25974", "fields": { "summary": "Android: Ti.Geolocation updates rarely on Android 8.0 while app is backgrounded", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "Medium", "id": "3" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } }, { "id": "56469", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "171554", "key": "TIMOB-25980", "fields": { "summary": "Android : How to disable FusedLocationProvider if it is already enabled ?", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "None", "id": "6" }, "issuetype": { "id": "7", "description": "gh.issue.story.desc", "name": "Story", "subtask": false } } } } ], "assignee": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2018-06-19T21:57:02.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" } ], "description": "Some tasks must be done in a background services but they are essential to an app (like playing audio in a music player, radio player or audiobook player). The problem is that when we use standard background services, Android can kill the service, resulting in a bad user experience.\r\n\r\nFrom the Android documentation:\r\n\r\n\"A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory.\" (1)\r\n\r\n\"By default services are background, meaning that if the system needs to kill them to reclaim more memory (such as to display a large page in a web browser), they can be killed without too much harm. You can set this flag if killing your service would be disruptive to the user, such as if your service is performing background music playback, so the user would notice if their music stopped playing.\" (2)\r\n\r\nIt will be very appreciated if we can use foreground services in Titanium without the need of writing a native Android module.\r\n\r\n# [http://developer.android.com/reference/android/app/Service.html#ProcessLifecycle]\r\n# [http://developer.android.com/reference/android/app/Service.html#startForeground(int,%20android.app.Notification)]", "attachment": [], "flagged": false, "summary": "Android: Add \"foreground\" service support", "creator": { "name": "dirleidionisio", "key": "dirleidionisio", "displayName": "Dirlei Dionísio", "active": true, "timeZone": "America/Sao_Paulo" }, "subtasks": [], "reporter": { "name": "dirleidionisio", "key": "dirleidionisio", "displayName": "Dirlei Dionísio", "active": true, "timeZone": "America/Sao_Paulo" }, "environment": "Android", "closedSprints": [ { "id": 1034, "state": "closed", "name": "2018 Sprint 10 SDK", "startDate": "2018-05-07T00:03:21.636Z", "endDate": "2018-05-21T00:03:00.000Z", "completeDate": "2018-05-20T20:54:58.928Z", "originBoardId": 114 }, { "id": 1035, "state": "closed", "name": "2018 Sprint 11 SDK", "startDate": "2018-05-20T20:57:43.542Z", "endDate": "2018-06-03T20:57:00.000Z", "completeDate": "2018-06-04T15:13:14.425Z", "originBoardId": 114 }, { "id": 1039, "state": "closed", "name": "2018 Sprint 12 SDK", "startDate": "2018-06-03T15:22:23.401Z", "endDate": "2018-06-17T15:22:00.000Z", "completeDate": "2018-06-18T20:45:36.363Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "285536", "author": { "name": "ragrawal", "key": "ragrawal", "displayName": "Ritu Agrawal", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Thank you for your valuable suggestion. Titanium SDK currently does not support foreground services so moving this feature request to engineering for further evaluation and prioritization.", "updateAuthor": { "name": "ragrawal", "key": "ragrawal", "displayName": "Ritu Agrawal", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-12-22T05:06:53.000+0000", "updated": "2013-12-22T05:06:53.000+0000" }, { "id": "289949", "author": { "name": "appcelerator@matejsimek.cz", "key": "appcelerator@matejsimek.cz", "displayName": "Matěj Šimek", "active": true, "timeZone": "Europe/Berlin" }, "body": "Some draft of mine: https://github.com/enzy/titanium_mobile/commit/a979da5d5887612d9fc0d297882f7518eb566c5b\r\n\r\nCurrently I don't know how to pass notification (NotificationProxy) to startForeground method.", "updateAuthor": { "name": "appcelerator@matejsimek.cz", "key": "appcelerator@matejsimek.cz", "displayName": "Matěj Šimek", "active": true, "timeZone": "Europe/Berlin" }, "created": "2014-01-28T09:22:55.000+0000", "updated": "2014-01-28T09:22:55.000+0000" }, { "id": "289953", "author": { "name": "karl.n", "key": "karl.n", "displayName": "Karl Nilsson", "active": true, "timeZone": "Europe/Berlin" }, "body": "Matěj: I don't think that will work. The services use a java-template that is included in the project by the _build.js script. I created a custom template and added the startForeground() call and successfully managed to start a foreground service. However, as soon as the app is killed (but the service keeps running) the javascript code stops running. After having looked at the source code deeper I came to the conclusion that the Kroll class is static, which means only one copy can be run, and that copy is killed along with the app process itself. So the problem seems to be much much deeper than just calling startForeground() etc. \r\n\r\nBut I am not a java programmer, so I may have misunderstood how the underlying code works.", "updateAuthor": { "name": "karl.n", "key": "karl.n", "displayName": "Karl Nilsson", "active": true, "timeZone": "Europe/Berlin" }, "created": "2014-01-28T10:00:08.000+0000", "updated": "2014-01-28T10:00:08.000+0000" }, { "id": "322530", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Would like to see an architecture proposal first on how to solve this.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-09-09T15:14:05.000+0000", "updated": "2014-09-09T15:14:05.000+0000" }, { "id": "413879", "author": { "name": "greg@snapithd.com", "key": "greg@snapithd.com", "displayName": "greg", "active": true, "timeZone": "Pacific/Auckland" }, "body": "There is an open source GPS tracker that handles this well on Android. Of course its written in Java, however I wonder if this may assist in working out how Appcelerator could be enhanced to support this functionality.\r\nhttp://bk.gnarf.org/creativity/bigbrothergps/", "updateAuthor": { "name": "greg@snapithd.com", "key": "greg@snapithd.com", "displayName": "greg", "active": true, "timeZone": "Pacific/Auckland" }, "created": "2017-03-20T19:42:43.000+0000", "updated": "2017-03-20T19:42:43.000+0000" }, { "id": "433873", "author": { "name": "clopez", "key": "clopez", "displayName": "Carlos Pérez López ", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Hi, something new? I need it for gps tracker in android oreo in background\r\n", "updateAuthor": { "name": "clopez", "key": "clopez", "displayName": "Carlos Pérez López ", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-01-31T08:06:12.000+0000", "updated": "2018-01-31T08:06:12.000+0000" }, { "id": "437082", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Android 8.0 and above automatically throttles location data collection while the app is backgrounded to about 3 times per hour. This is regardless if your app targets Android 8 or not. The only solution is to use a foreground service.\r\nhttps://developer.android.com/about/versions/oreo/background-location-limits.html\r\n\r\nAndroid 8.0 (aka: API Level 26) has a new {{Context.startforegroundservice()}} method, but I don't know if we need to call it over {{Context.startService()}} since you're still required to call {{Service.startForeground()}} afterwards within 5 seconds (this is in regards to location data throttling). This requires research and will determine how to implement this in Titanium.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-04-23T22:11:31.000+0000", "updated": "2018-04-23T22:11:31.000+0000" }, { "id": "437084", "author": { "name": "greg@snapithd.com", "key": "greg@snapithd.com", "displayName": "greg", "active": true, "timeZone": "Pacific/Auckland" }, "body": "Rainer Schleevoigt is doing some work on this which may help...\r\n\r\nhttps://github.com/AppWerft/Ti.LocationUpdatesService\r\n\r\n\r\n", "updateAuthor": { "name": "greg@snapithd.com", "key": "greg@snapithd.com", "displayName": "greg", "active": true, "timeZone": "Pacific/Auckland" }, "created": "2018-04-23T22:33:52.000+0000", "updated": "2018-04-23T22:34:15.000+0000" }, { "id": "437730", "author": { "name": "Pietro", "key": "pietro", "displayName": "Pietro Granati", "active": true, "timeZone": "Europe/Rome" }, "body": "Hey guys! Any news? I'm struggling to get location updates like on android 7 right know I'm blocked", "updateAuthor": { "name": "Pietro", "key": "pietro", "displayName": "Pietro Granati", "active": true, "timeZone": "Europe/Rome" }, "created": "2018-05-17T14:14:52.000+0000", "updated": "2018-05-17T14:14:52.000+0000" }, { "id": "437738", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "The current plan is to add this feature to Titanium 7.3.0, but we don't have an ETA for when that will be released yet.\r\n\r\nYou may want to try the module mentioned by Greg above. I haven't tried it, but I can see in its code that it calls {{Service.startForeground()}} which should do the job.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-05-17T18:23:38.000+0000", "updated": "2018-05-17T18:23:38.000+0000" }, { "id": "437745", "author": { "name": "greg@snapithd.com", "key": "greg@snapithd.com", "displayName": "greg", "active": true, "timeZone": "Pacific/Auckland" }, "body": "As far as I can tell the AppWerft code is not currently working. It's close... but not quite...", "updateAuthor": { "name": "greg@snapithd.com", "key": "greg@snapithd.com", "displayName": "greg", "active": true, "timeZone": "Pacific/Auckland" }, "created": "2018-05-17T21:02:07.000+0000", "updated": "2018-05-17T21:02:07.000+0000" }, { "id": "437814", "author": { "name": "Pietro", "key": "pietro", "displayName": "Pietro Granati", "active": true, "timeZone": "Europe/Rome" }, "body": "I appreciate your answer Joshua, but for me background process is the key for some of my apps, new clients with android 8 can't use it.\r\nSInce 31 people start watching this, I think it's time to set priority high.", "updateAuthor": { "name": "Pietro", "key": "pietro", "displayName": "Pietro Granati", "active": true, "timeZone": "Europe/Rome" }, "created": "2018-05-21T16:00:03.000+0000", "updated": "2018-05-21T16:00:03.000+0000" }, { "id": "437879", "author": { "name": "amukherjee", "key": "amukherjee", "displayName": "Abir Mukherjee", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Bumping priority. Moving to 7.4.0 to be worked on as first priority.", "updateAuthor": { "name": "amukherjee", "key": "amukherjee", "displayName": "Abir Mukherjee", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-05-23T17:08:39.000+0000", "updated": "2018-05-23T17:08:39.000+0000" }, { "id": "437890", "author": { "name": "amukherjee", "key": "amukherjee", "displayName": "Abir Mukherjee", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Thanks [~jquick], we'll move it back to 7.3.0.", "updateAuthor": { "name": "amukherjee", "key": "amukherjee", "displayName": "Abir Mukherjee", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-05-23T18:10:31.000+0000", "updated": "2018-05-23T18:10:31.000+0000" }, { "id": "437960", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "PR (master): https://github.com/appcelerator/titanium_mobile/pull/10076", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-05-26T03:53:23.000+0000", "updated": "2018-05-26T03:53:23.000+0000" }, { "id": "437962", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "*Note to everyone:*\r\nIf you start a \"Service\", but never stop it upon app exit, then the service will keep the prior JavaScript runtime alive as per the design choice made by [TIMOB-9831]. The negative consequence of this is that when you attempt to restart the app (tap on the app in the app list), then you'll be stuck on the splash screen and the \"app.js\" won't get loaded until the service has been stopped. Only one JavaScript runtime can exist at a time and we can't spawn a new one until the service has released the last one. (I don't necessarily agree with this design, but changing it now would be a \"breaking-change\" for those who depend on it.)\r\n\r\nThat said, there are 2 solutions to address this concern.\r\n\r\n*Solution 1:*\r\nStop the service upon app exit. You can do this by listening for the \"close\" event from the root window as follows.\r\n{code:javascript}\r\nvar intent = Ti.Android.createServiceIntent({\r\n\turl: \"Service.js\",\r\n});\r\nTi.Android.startService(intent);\r\n\r\nvar window = Ti.UI.createWindow();\r\nwindow.addEventListener(\"close\", function(e) {\r\n\tTi.Android.stopService(intent);\r\n});\r\nwindow.open();\r\n{code}\r\n\r\n*Solution 2:*\r\nPrevent the root window from being closed by listening for its \"androidback\" event and use an intent to go to the home-screen (simulates a Home button press). This effectively makes your Android app work more like iOS.\r\n\r\n{code:javascript}\r\nvar window = Ti.UI.createWindow();\r\nvar label = Ti.UI.createLabel({ text: \"1\" });\r\nwindow.add(label);\r\nwindow.addEventListener(\"androidback\", function(e) {\r\n\t// If the back key was press, cancel it and go to the home-screen instead.\r\n\tvar intent = Ti.Android.createIntent({\r\n\t\taction: Ti.Android.ACTION_MAIN,\r\n\t});\r\n\tintent.addCategory(Ti.Android.CATEGORY_HOME);\r\n\tintent.setFlags(Ti.Android.FLAG_ACTIVITY_NEW_TASK);\r\n\tTi.Android.currentActivity.startActivity(intent);\r\n});\r\nwindow.open();\r\n\r\nsetInterval(function() {\r\n\tlabel.text = (Number(label.text) + 1).toString();\r\n}, 1000);\r\n{code}\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-05-26T04:13:14.000+0000", "updated": "2018-05-26T04:17:04.000+0000" }, { "id": "437970", "author": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "body": "I have cherry-picked the changes from [#10076|https://github.com/appcelerator/titanium_mobile/pull/10076] and [#9945|https://github.com/appcelerator/titanium_mobile/pull/9945] into 7_1_X, so developers can use it with their stable GA until 7.3.0 gets released. Important notes before downloading the custom SDK:\r\n\r\n- It is \"7.1.2\", a 7.1.1.GA + the changes of this ticket\r\n- The changes have not passed the QE-validation so far\r\n- The custom SDK is no official build, so please use with caution!\r\n\r\nDownload: https://www.dropbox.com/s/k9n73ow64hq9f51/mobilesdk-7.1.2-osx.zip?dl=1", "updateAuthor": { "name": "hknoechel", "key": "hansknoechel", "displayName": "Hans Knöchel", "active": true, "timeZone": "Europe/Berlin" }, "created": "2018-05-27T18:40:32.000+0000", "updated": "2018-05-27T18:40:32.000+0000" }, { "id": "437976", "author": { "name": "Pietro", "key": "pietro", "displayName": "Pietro Granati", "active": true, "timeZone": "Europe/Rome" }, "body": "Hans you made my day!", "updateAuthor": { "name": "Pietro", "key": "pietro", "displayName": "Pietro Granati", "active": true, "timeZone": "Europe/Rome" }, "created": "2018-05-28T10:53:09.000+0000", "updated": "2018-05-28T10:53:09.000+0000" }, { "id": "437977", "author": { "name": "pako.artal@htg-express.com", "key": "pako.artal@htg-express.com", "displayName": "pako.artal@htg-express.com", "active": true, "timeZone": "Europe/Madrid" }, "body": "Hi,\r\nThanks a lot for the fix and for the cherry pick!\r\nI tested the cherry picked sdk with 4 phones :\r\n* Samsung Galaxy J5 / Android 7.1.1\r\n* BQ Aquaris M5 / android 7.\r\n* Google pixel 2 / Android 8\r\n* Sony Xperia F8331 / Android 8.0.0\r\n\r\nWith the same code It's working for many hours in the the Samsung, BQ and Pixel, but for the Sony I got this error:\r\n\r\n{code}\r\n[ERROR] : KrollProxy: (main) [2370,36837] Error creating proxy\r\n[ERROR] : KrollProxy: java.lang.IllegalStateException: Creation arguments must contain intent\r\n[ERROR] : KrollProxy: \tat ti.modules.titanium.android.PendingIntentProxy.handleCreationArgs(PendingIntentProxy.java:58)\r\n[ERROR] : KrollProxy: \tat org.appcelerator.kroll.KrollProxy.setupProxy(KrollProxy.java:129)\r\n[ERROR] : KrollProxy: \tat org.appcelerator.kroll.KrollProxy.createProxy(KrollProxy.java:138)\r\n[ERROR] : KrollProxy: \tat org.appcelerator.kroll.runtime.v8.V8Runtime.nativeRunModule(Native Method)\r\n[ERROR] : KrollProxy: \tat org.appcelerator.kroll.runtime.v8.V8Runtime.doRunModule(V8Runtime.java:187)\r\n[ERROR] : KrollProxy: \tat org.appcelerator.kroll.KrollRuntime.runModule(KrollRuntime.java:247)\r\n[ERROR] : KrollProxy: \tat ti.modules.titanium.android.TiJSService.executeServiceCode(TiJSService.java:74)\r\n[ERROR] : KrollProxy: \tat ti.modules.titanium.android.TiJSService.start(TiJSService.java:96)\r\n[ERROR] : KrollProxy: \tat ti.modules.titanium.android.TiJSService.onStartCommand(TiJSService.java:47)\r\n[ERROR] : KrollProxy: \tat android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3544)\r\n[ERROR] : KrollProxy: \tat android.app.ActivityThread.-wrap20(Unknown Source:0)\r\n[ERROR] : KrollProxy: \tat android.app.ActivityThread$H.handleMessage(ActivityThread.java:1703)\r\n[ERROR] : KrollProxy: \tat android.os.Handler.dispatchMessage(Handler.java:105)\r\n[ERROR] : KrollProxy: \tat android.os.Looper.loop(Looper.java:251)\r\n[ERROR] : KrollProxy: \tat android.app.ActivityThread.main(ActivityThread.java:6572)\r\n[ERROR] : KrollProxy: \tat java.lang.reflect.Method.invoke(Native Method)\r\n[ERROR] : KrollProxy: \tat com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)\r\n[ERROR] : KrollProxy: \tat com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)\r\n[ERROR] : JavaObject: !!! OH NO! We tried to grab a Java Object back out of the reference table, but it must have been GC'd, because it's null! Key: 131\r\n[WARN] : TiNotification: (main) [5,36842] Falling back to default notification channel.\r\n[WARN] : TiNotification: It is highly advised to create your own notification channel using Ti.Android.NotificationManager.createNotificationChannel()\r\n[ERROR] : KrollProxy: (main) [0,36842] Error creating proxy\r\n[ERROR] : KrollProxy: java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.PendingIntent ti.modules.titanium.android.PendingIntentProxy.getPendingIntent()' on a null object reference\r\n[ERROR] : KrollProxy: \tat ti.modules.titanium.android.notificationmanager.NotificationProxy.setContentIntent(NotificationProxy.java:304)\r\n[ERROR] : KrollProxy: \tat ti.modules.titanium.android.notificationmanager.NotificationProxy.handleCreationDict(NotificationProxy.java:96)\r\n[ERROR] : KrollProxy: \tat org.appcelerator.kroll.KrollProxy.handleCreationArgs(KrollProxy.java:197)\r\n[ERROR] : KrollProxy: \tat org.appcelerator.kroll.KrollProxy.setupProxy(KrollProxy.java:129)\r\n[ERROR] : KrollProxy: \tat org.appcelerator.kroll.KrollProxy.createProxy(KrollProxy.java:138)\r\n[ERROR] : KrollProxy: \tat org.appcelerator.kroll.runtime.v8.V8Runtime.nativeRunModule(Native Method)\r\n[ERROR] : KrollProxy: \tat org.appcelerator.kroll.runtime.v8.V8Runtime.doRunModule(V8Runtime.java:187)\r\n[ERROR] : KrollProxy: \tat org.appcelerator.kroll.KrollRuntime.runModule(KrollRuntime.java:247)\r\n[ERROR] : KrollProxy: \tat ti.modules.titanium.android.TiJSService.executeServiceCode(TiJSService.java:74)\r\n[ERROR] : KrollProxy: \tat ti.modules.titanium.android.TiJSService.start(TiJSService.java:96)\r\n[ERROR] : KrollProxy: \tat ti.modules.titanium.android.TiJSService.onStartCommand(TiJSService.java:47)\r\n[ERROR] : KrollProxy: \tat android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3544)\r\n[ERROR] : KrollProxy: \tat android.app.ActivityThread.-wrap20(Unknown Source:0)\r\n[ERROR] : KrollProxy: \tat android.app.ActivityThread$H.handleMessage(ActivityThread.java:1703)\r\n[ERROR] : KrollProxy: \tat android.os.Handler.dispatchMessage(Handler.java:105)\r\n[ERROR] : KrollProxy: \tat android.os.Looper.loop(Looper.java:251)\r\n[ERROR] : KrollProxy: \tat android.app.ActivityThread.main(ActivityThread.java:6572)\r\n[ERROR] : KrollProxy: \tat java.lang.reflect.Method.invoke(Native Method)\r\n[ERROR] : KrollProxy: \tat com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)\r\n[ERROR] : KrollProxy: \tat com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)\r\n[ERROR] : JavaObject: !!! OH NO! We tried to grab a Java Object back out of the reference table, but it must have been GC'd, because it's null! Key: 132\r\n[WARN] : W/System.err: java.lang.RuntimeException: Notification object argument cannot be null.\r\n[WARN] : W/System.err: \tat org.appcelerator.titanium.proxy.ServiceProxy.foregroundNotify(ServiceProxy.java:136)\r\n[WARN] : W/System.err: \tat org.appcelerator.kroll.runtime.v8.V8Runtime.nativeRunModule(Native Method)\r\n[WARN] : W/System.err: \tat org.appcelerator.kroll.runtime.v8.V8Runtime.doRunModule(V8Runtime.java:187)\r\n[WARN] : W/System.err: \tat org.appcelerator.kroll.KrollRuntime.runModule(KrollRuntime.java:247)\r\n[WARN] : W/System.err: \tat ti.modules.titanium.android.TiJSService.executeServiceCode(TiJSService.java:74)\r\n[WARN] : W/System.err: \tat ti.modules.titanium.android.TiJSService.start(TiJSService.java:96)\r\n[WARN] : W/System.err: \tat ti.modules.titanium.android.TiJSService.onStartCommand(TiJSService.java:47)\r\n[WARN] : W/System.err: \tat android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3544)\r\n[WARN] : W/System.err: \tat android.app.ActivityThread.-wrap20(Unknown Source:0)\r\n[WARN] : W/System.err: \tat android.app.ActivityThread$H.handleMessage(ActivityThread.java:1703)\r\n[WARN] : W/System.err: \tat android.os.Handler.dispatchMessage(Handler.java:105)\r\n[WARN] : W/System.err: \tat android.os.Looper.loop(Looper.java:251)\r\n[WARN] : W/System.err: \tat android.app.ActivityThread.main(ActivityThread.java:6572)\r\n[WARN] : W/System.err: \tat java.lang.reflect.Method.invoke(Native Method)\r\n[WARN] : W/System.err: \tat com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)\r\n[WARN] : W/System.err: \tat com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)\r\n[ERROR] : TiExceptionHandler: (main) [2,36844] ----- Titanium Javascript Runtime Error -----\r\n[ERROR] : TiExceptionHandler: (main) [0,36844] - In /bGeo/Ti.Geo.Timer.js:13,27\r\n[ERROR] : TiExceptionHandler: (main) [0,36844] - Message: Uncaught Notification object argument cannot be null.\r\n[ERROR] : TiExceptionHandler: (main) [0,36844] - Source: Ti.Android.currentService.foregroundNotify(notificationId,Ti.Android.createNotification({\r\n[ERROR] : V8Exception: Exception occurred at /bGeo/Ti.Geo.Timer.js:13: Uncaught Notification object argument cannot be null.\r\n[ERROR] : V8Exception: Notification object argument cannot be null.\r\n{code}\r\n\r\nMy code:\r\n\r\n{code: JavaScript}\r\nvar notificationId = 123;\r\nTi.Android.currentService.foregroundNotify(notificationId, Ti.Android.createNotification({\r\n\tcontentTitle : \"XXXXX\",\r\n\tcontentText : \"Localizando ...\",\r\n\tcontentIntent : Ti.Android.createPendingIntent({\r\n\t\t// Using the launch intent will resume the app when tapped.\r\n\t\tintent : Ti.App.Android.launchIntent,\r\n\t}),\r\n}));\r\n{code}\r\n\r\nIn my tiapp.xml I have.\r\n\r\n{code:xml}\r\n\r\n\r\n \r\n\r\n{code}\r\n\r\nShould I have created a Notification Channel ?", "updateAuthor": { "name": "pako.artal@htg-express.com", "key": "pako.artal@htg-express.com", "displayName": "pako.artal@htg-express.com", "active": true, "timeZone": "Europe/Madrid" }, "created": "2018-05-28T14:19:51.000+0000", "updated": "2018-05-28T14:19:51.000+0000" }, { "id": "437993", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~pako.artal@htg-express.com], it sounds like the {{launchIntent}} property is returning {{null}}. We'll look into it.", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-05-29T18:37:19.000+0000", "updated": "2018-05-29T18:37:19.000+0000" }, { "id": "437994", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "And ideally, yes, you should create your own notification channel on Android 8.0 and above. That way you can control the name and importance level given to it, as seen by the end-user. But this is not the cause of the error that you are seeing.\r\n\r\n{code:javascript}\r\nvar channel = null;\r\nif (Ti.Platform.Android.API_LEVEL >= 26) {\r\n\tchannel = Ti.Android.NotificationManager.createNotificationChannel({\r\n\t\t// Unique string ID you assign to the channel.\r\n\t\tid: \"my_channel_id\",\r\n\t\t// Channel name seen by the end-user.\r\n\t\tname: \"My Channel Name\",\r\n\t\timportance: Ti.Android.IMPORTANCE_DEFAULT,\r\n\t});\r\n}\r\nTi.Android.currentService.foregroundNotify(123, Ti.Android.createNotification({\r\n\tcontentTitle: \"Foreground Service\",\r\n\tcontentText: \"Content Text\",\r\n\tchannelId: channel ? channel.id : null,\r\n\tcontentIntent: Ti.Android.createPendingIntent({\r\n\t\t// Using the launch intent will resume the app when tapped.\r\n\t\tintent: Ti.App.Android.launchIntent,\r\n\t}),\r\n}));\r\n{code}\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-05-29T18:42:16.000+0000", "updated": "2018-05-29T18:42:16.000+0000" }, { "id": "438000", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~pako.artal@htg-express.com],\r\n\r\nAfter some investigation, it turns out the native Java [Android.getActivity()|https://developer.android.com/reference/android/app/Activity#getIntent()] method can in fact return {{null}} in rare cases. Looks like you're running into one of them. This is the method that Titanium's {{Ti.App.Android.launchIntent}} and {{Ti.Android.Activity.intent}} properties acquire the launch intent from.\r\nhttps://stackoverflow.com/questions/37856407/can-activity-getintent-ever-return-null\r\n\r\nSo, a simple solution to this problem is to set up the notification to not do anything when tapped on. You can do this by setting up the pending-intent with an empty intent like the below. Note that the foreground notification won't disappear when tapped on, making this a viable solution.\r\n{code:javascript}\r\ncontentIntent: Ti.Android.createPendingIntent({\r\n\tintent: Ti.Android.createIntent({}),\r\n}),\r\n{code}\r\n\r\nOr you can do something like the below. Check if {{launchIntent}} is {{null}}, and if it is, use an empty intent instead.\r\n{code:javascript}\r\nfunction getAppResumeIntent() {\r\n\tvar intent = Ti.App.Android.launchIntent;\r\n\tif (!intent) {\r\n\t\tintent = Ti.Android.createIntent({});\r\n\t}\r\n\treturn intent;\r\n}\r\nTi.Android.currentService.foregroundNotify(123, Ti.Android.createNotification({\r\n\tcontentTitle: \"Foreground Service\",\r\n\tcontentText: \"Content Text\",\r\n\tcontentIntent: Ti.Android.createPendingIntent({\r\n\t\tintent: getAppResumeIntent(),\r\n\t}),\r\n}));\r\n{code}\r\n", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-05-29T23:05:56.000+0000", "updated": "2018-05-29T23:05:56.000+0000" }, { "id": "438164", "author": { "name": "engwei", "key": "engwei", "displayName": "engwei", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Thanks for your work on this!\r\n\r\nIs it possible to update the notification text after it has been set?\r\n\r\nI was trying to change the text every time a location is updated with something like 'Last location update 15:12' but it doesn't seem to do it consistently.", "updateAuthor": { "name": "engwei", "key": "engwei", "displayName": "engwei", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-06-06T09:00:38.000+0000", "updated": "2018-06-06T09:00:38.000+0000" }, { "id": "438173", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{quote}Is it possible to update the notification text after it has been set?{quote}\r\n\r\n[~engwei], yes, you can update the notification's text by calling the {{foregroundNotify()}} method again with the same notification ID you used before. This means that you cannot simply just update the notification object's text. The updated notification object has to be re-posted to the status bar via a call to {{foregroundNotify()}}. This is how it works at the native level.\r\n\r\nAlso note that the same is true for notifications posted via {{NotificationManager.notify()}}. If you want to update a notification posted via {{NotificationManager}}, then you must call its {{notify()}} method again with the same notification ID you used before. We made sure to make the behavior consistent for foreground services.\r\n\r\nI hope this helps!", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-06-06T17:51:07.000+0000", "updated": "2018-06-06T17:54:16.000+0000" }, { "id": "438174", "author": { "name": "engwei", "key": "engwei", "displayName": "engwei", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Thanks Joshua that works perfectly. I was trying to use setLatestEventInfo() and that seemed to only work periodically. Your method works perfectly.\r\nThanks", "updateAuthor": { "name": "engwei", "key": "engwei", "displayName": "engwei", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-06-06T18:06:36.000+0000", "updated": "2018-06-06T18:06:36.000+0000" }, { "id": "438246", "author": { "name": "engwei", "key": "engwei", "displayName": "engwei", "active": true, "timeZone": "America/Los_Angeles" }, "body": "I received this crash today which I think looks like it's related to foreground service:\r\n\r\njava.lang.RuntimeException: Unable to resume activity {com.ingelby.grititranger/org.appcelerator.titanium.TiActivity}: java.lang.NumberFormatException: s == null\r\n\tat android.app.ActivityThread.performResumeActivity(ActivityThread.java:3788)\r\n\tat android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3828)\r\n\tat android.app.ActivityThread$H.handleMessage(ActivityThread.java:1746)\r\n\tat android.os.Handler.dispatchMessage(Handler.java:105)\r\n\tat android.os.Looper.loop(Looper.java:164)\r\n\tat android.app.ActivityThread.main(ActivityThread.java:6938)\r\n\tat java.lang.reflect.Method.invoke(Native Method)\r\n\tat com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)\r\n\tat com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)\r\nCaused by: java.lang.NumberFormatException: s == null\r\n\tat java.lang.Integer.parseInt(Integer.java:570)\r\n\tat java.lang.Integer.parseInt(Integer.java:643)\r\n\tat com.appcelerator.aps.APSAnalyticsModel.addEvent(APSAnalyticsModel.java:78)\r\n\tat com.appcelerator.aps.APSAnalyticsHelper.sendAnalyticsEvent(APSAnalyticsHelper.java:518)\r\n\tat com.appcelerator.aps.APSAnalyticsHelper.postAnalyticsEvent(APSAnalyticsHelper.java:506)\r\n\tat com.appcelerator.aps.APSAnalytics.sendAppForegroundEvent(APSAnalytics.java:133)\r\n\tat org.appcelerator.titanium.TiBaseActivity.onResume(TiBaseActivity.java:1323)\r\n\tat org.appcelerator.titanium.TiActivity.onResume(TiActivity.java:65)\r\n\tat android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1361)\r\n\tat android.app.Activity.performResume(Activity.java:7344)\r\n\tat android.app.ActivityThread.performResumeActivity(ActivityThread.java:3763)", "updateAuthor": { "name": "engwei", "key": "engwei", "displayName": "engwei", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-06-08T10:27:48.000+0000", "updated": "2018-06-08T10:27:48.000+0000" }, { "id": "438253", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-06-08T17:53:24.000+0000", "updated": "2018-06-08T17:53:24.000+0000" }, { "id": "438535", "author": { "name": "lchoudhary", "key": "lchoudhary", "displayName": "Lokesh Choudhary", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Verified the fix in SDK 7.3.0.v20180618182516.\r\nClosing.", "updateAuthor": { "name": "lchoudhary", "key": "lchoudhary", "displayName": "Lokesh Choudhary", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2018-06-19T21:56:48.000+0000", "updated": "2018-06-19T21:56:48.000+0000" } ], "maxResults": 32, "total": 32, "startAt": 0 } } }