Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

impr(android): implement foregroundServiceType parameter #11197

Merged
merged 12 commits into from Oct 2, 2019

Conversation

garymathews
Copy link
Contributor

@garymathews garymathews commented Sep 5, 2019

  • Implement foregroundServiceType parameter into Ti.Android.Service.foregroundNotify
TEST CASE

tiapp.xml

<android>
  <manifest>
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
  </manifest>
  <services>
    <service url="locationService.js" android:foregroundServiceType="location"/>
  </services>
</android>

locationService.js

console.log(`Background location service started.`);

// Create foreground service.
Ti.Android.currentService.foregroundNotify(
	123,
	Ti.Android.createNotification({
		contentTitle: "Background Location Service",
		contentText: "Obtaining location data...",
		contentIntent: Ti.Android.createPendingIntent({
			intent: Ti.App.Android.launchIntent || Ti.Android.createIntent(),
		})
	}),
	Ti.Android.FOREGROUND_SERVICE_TYPE_LOCATION
);

app.js

const win = Ti.UI.createWindow({ backgroundColor: 'gray', layout: 'vertical' });
const backgroundServiceBtn = Ti.UI.createButton({ title: 'START BACKGROUND SERVICE' });
const listView = Ti.UI.createListView();

let count = 1;
let service = null;

// Set accuracy to high
Ti.Geolocation.accuracy = Ti.Geolocation.ACCURACY_HIGH;
 
// Enable manual configuration via location providers.
Ti.Geolocation.Android.manualMode = true;
 
// Define a location provider.
Ti.Geolocation.Android.addLocationProvider(
    Ti.Geolocation.Android.createLocationProvider({
        name: Ti.Geolocation.Android.PROVIDER_GPS,
        minUpdateDistance: 0,
        minUpdateTime: 5000
    })
);
 
function getLocation () {

    // Create location event listener.
    Ti.Geolocation.addEventListener('location', e => {

        // Create new section for location data.
        let section = Ti.UI.createListSection({ headerTitle: `#${count++} - ${new Date().toTimeString()}` });
        if (e.success) {
            if (e.coords) {
                e = e.coords;
            }

            // Insert location data.
            section.setItems([
                { properties: { title: 'LOCATION:\n' + e.latitude + ', ' + e.longitude, color: 'green' } },
                { properties: { title: 'ALTITUDE:\n' + e.altitude, color: 'green' } },
                { properties: { title: 'ACCURACY:\n' + e.accuracy, color: 'green' } }
            ]);

        } else {

            // Oops! Something bad happened.
            section.setItems([
                { properties: { title: 'ERROR:\n' + e.error, color: 'red' } }
            ]);
        }

        // Add section to listView
        listView.appendSection(section);
    });
}
 
win.addEventListener('open', () => {

    // Request location permissions.
    Ti.Geolocation.requestLocationPermissions(Ti.Geolocation.AUTHORIZATION_ALWAYS, e => {
        if (e.success) {
            getLocation();
        } else {
            alert('Could not obtain location permissions.');
        }
    });
});

backgroundServiceBtn.addEventListener('click', () => {
    if (!service) {

        // Create background location service.
        const intent = Ti.Android.createServiceIntent({ url : 'locationService.js' });
        service = Ti.Android.createService(intent);

        console.log('Starting background location service...');

        // Android 10+ request background location permissions.
        if (parseInt(Ti.Platform.version.split('.')[0]) >= 10) {
            Ti.Android.requestPermissions([ 'android.permission.ACCESS_BACKGROUND_LOCATION' ], e => {
                if (e.success) {
                    service.start();
                    backgroundServiceBtn.title = 'STOP BACKGROUND SERVICE';
                } else {
                    alert('Could not obtain background location permissions.');
                }
            });
        } else {
            service.start();
            backgroundServiceBtn.title = 'STOP BACKGROUND SERVICE';
        }

    } else {
        console.log('Stopping background location service...');
        
        service.stop();
        backgroundServiceBtn.title = 'START BACKGROUND SERVICE';
    }
});
 
win.add([backgroundServiceBtn, listView]);
win.open();

JIRA Ticket

@garymathews garymathews added this to the 8.3.0 milestone Sep 5, 2019
@build build requested review from a team September 5, 2019 19:27
@build build added the docs label Sep 5, 2019
@build
Copy link
Contributor

build commented Sep 5, 2019

Warnings
⚠️

Commit 1b592b216675230e592db15ded3585598d56b105 has a message "impl(android): implement foregroundServiceType parameter" giving 1 errors:

  • type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test]
Messages
📖

💾 Here's the generated SDK zipfile.

📖

✅ All tests are passing
Nice one! All 3898 tests are passing.
(There are 475 skipped tests not included in that total)

📖

🚨 This PR has one or more commits with warnings/errors for commit messages not matching our configuration. You may want to squash merge this PR and edit the message to match our conventions, or ask the original developer to modify their history.

Generated by 🚫 dangerJS against a2d5c4f

@sgtcoolguy sgtcoolguy changed the base branch from 8_3_X to master September 9, 2019 18:04
@sgtcoolguy sgtcoolguy changed the title impr(android)(8_3_X): implement foregroundServiceType parameter impr(android): implement foregroundServiceType parameter Sep 9, 2019
Copy link
Contributor

@jquick-axway jquick-axway left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CR: Pass

@keerthi1032
Copy link
Contributor

keerthi1032 commented Sep 17, 2019

@garymathews on clicking start background button error throws.

[ERROR] :  TiServiceProxy: (main) [14,25829] foregroundServiceType 0x00000008 is not a subset of foregroundServiceType attribute 0x00000000 in service element of manifest file

[ERROR] :  TiServiceProxy: java.lang.IllegalArgumentException: foregroundServiceType 0x00000008 is not a subset of foregroundServiceType attribute 0x00000000 in service element of manifest file

[ERROR] :  TiServiceProxy: at android.os.Parcel.createException(Parcel.java:2075)

[ERROR] :  TiServiceProxy: at android.os.Parcel.readException(Parcel.java:2039)

[ERROR] :  TiServiceProxy: at android.os.Parcel.readException(Parcel.java:1987)

[ERROR] :  TiServiceProxy: at android.app.IActivityManager$Stub$Proxy.setServiceForeground(IActivityManager.java:6136)

[ERROR] :  TiServiceProxy: at android.app.Service.startForeground(Service.java:742)

[ERROR] :  TiServiceProxy: at org.appcelerator.titanium.proxy.ServiceProxy$2.run(ServiceProxy.java:366)

[ERROR] :  TiServiceProxy: at org.appcelerator.kroll.KrollProxy.runWithHandler(KrollProxy.java:454)

[ERROR] :  TiServiceProxy: at org.appcelerator.kroll.KrollProxy.runOnMainThread(KrollProxy.java:426)

[ERROR] :  TiServiceProxy: at org.appcelerator.titanium.proxy.ServiceProxy.updateForegroundState(ServiceProxy.java:261)

[ERROR] :  TiServiceProxy: at org.appcelerator.titanium.proxy.ServiceProxy.foregroundNotify(ServiceProxy.java:152)

[ERROR] :  TiServiceProxy: at org.appcelerator.kroll.runtime.v8.V8Runtime.nativeRunModule(Native Method)

[ERROR] :  TiServiceProxy: at org.appcelerator.kroll.runtime.v8.V8Runtime.doRunModule(V8Runtime.java:162)

[ERROR] :  TiServiceProxy: at org.appcelerator.kroll.KrollRuntime.runModule(KrollRuntime.java:211)

[ERROR] :  TiServiceProxy: at ti.modules.titanium.android.TiJSService.executeServiceCode(TiJSService.java:74)

[ERROR] :  TiServiceProxy: at ti.modules.titanium.android.TiJSService.start(TiJSService.java:96)

[ERROR] :  TiServiceProxy: at org.appcelerator.titanium.proxy.ServiceProxy.invokeBoundService(ServiceProxy.java:235)

[ERROR] :  TiServiceProxy: at org.appcelerator.titanium.proxy.ServiceProxy$1.onServiceConnected(ServiceProxy.java:188)

[ERROR] :  TiServiceProxy: at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1948)

[ERROR] :  TiServiceProxy: at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1980)

[ERROR] :  TiServiceProxy: at android.os.Handler.handleCallback(Handler.java:883)

[ERROR] :  TiServiceProxy: at android.os.Handler.dispatchMessage(Handler.java:100)

[ERROR] :  TiServiceProxy: at android.os.Looper.loop(Looper.java:214)

[ERROR] :  TiServiceProxy: at android.app.ActivityThread.main(ActivityThread.java:7356)

[ERROR] :  TiServiceProxy: at java.lang.reflect.Method.invoke(Native Method)

[ERROR] :  TiServiceProxy: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)

[ERROR] :  TiServiceProxy: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

[ERROR] :  TiServiceProxy: Caused by: android.os.RemoteException: Remote stack trace:

[ERROR] :  TiServiceProxy: at com.android.server.am.ActiveServices.setServiceForegroundInnerLocked(ActiveServices.java:1276)

[ERROR] :  TiServiceProxy: at com.android.server.am.ActiveServices.setServiceForegroundLocked(ActiveServices.java:914)

[ERROR] :  TiServiceProxy: at com.android.server.am.ActivityManagerService.setServiceForeground(ActivityManagerService.java:13968)

[ERROR] :  TiServiceProxy: at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2784)

[ERROR] :  TiServiceProxy: at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2741)

@garymathews
Copy link
Contributor Author

garymathews commented Sep 23, 2019

@keerthi1032 Could you re-test this? I forgot to include the android:foregroundServiceType tag in my test case:

tiapp.xml
...
<service url="locationService.js" android:foregroundServiceType="location"/>
...

@ssjsamir ssjsamir self-requested a review September 25, 2019 14:26
Copy link
Contributor

@ssjsamir ssjsamir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FR Passed: Service.foregroundNotify() now supports "foregroundServiceType" for Android Q. Tested with the test case mentioned above.

Note: for the test case I changed the backgroundServiceBtn.addEventListener to include service = null after the final else.

console.log('Stopping background location service...');

        service.stop();
        backgroundServiceBtn.title = 'START BACKGROUND SERVICE';
        service = null;

Test Environment

MacOS Catalina 10.15 Beta
Node.js ^8.11.1
Android Pixel XL 7.1 Emulator 
"NPM":"4.2.15","CLI":"7.1.1"
Java Version 1.8.0_131
Android NDK:  12.1.2977051

@sgtcoolguy sgtcoolguy merged commit 9ca5864 into tidev:master Oct 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants