The Question
I'm working on a module to create a foreground service for android. At first I thought this would be a daunting task, but as it turns out it was fairly straight forward. I want to be clear about what my question is here,
so please note this:
My service runs, the JS in my service runs, all this in the foreground, no less. My issue is that once I close the app, my JS stops running, unlike Titanium's built in background services. The service doesn't restart after app close, it just keeps going, which I like, but this is also unlike Titanium's built in background services, for what it's worth.
Thus, my question is:
How can I prevent my JS from stopping after I close the application and allow it to perpetuate as the service does, similarly to how Titanium currently does with its background services. What steps are necessary to fulfill this?
The Code
My Module's proxy method for starting the service:@Kroll.method
public void startForegroundService(String jsFile)
{
Intent serviceIntent = new Intent();
serviceIntent.setClassName(TiApplication.getInstance().getApplicationContext(), "com.powereddynamics.foregroundservice.ForegroundService");
serviceIntent.putExtra("jsUrl", jsFile);
TiApplication.getInstance().startService(serviceIntent);
}
The Service code which extends TiBaseService:package com.powereddynamics.foregroundservice;
import org.appcelerator.titanium.TiApplication;
import org.appcelerator.kroll.*;
import org.appcelerator.kroll.util.*;
import org.appcelerator.titanium.TiC;
import org.appcelerator.titanium.util.*;
import org.appcelerator.titanium.proxy.ServiceProxy;
import org.appcelerator.titanium.TiBaseService;
import android.R;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Intent;
import android.util.Log;
public class ForegroundService extends TiBaseService{//Service {
private String jsFile = "";
ServiceProxy proxy;
public ForegroundService()
{
super();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
jsFile = intent.getStringExtra("jsUrl");
proxy = createProxy(intent);
initialize();
return(START_REDELIVER_INTENT);
}
private void initialize() {
/*KrollRuntime.getInstance().evalString(
KrollAssetHelper.readAsset(getPath(jsFile)),
getPath(jsFile));*/
KrollRuntime.getInstance().runModule(KrollAssetHelper.readAsset(getPath(jsFile)), getPath(jsFile), proxy);
Log.w(getClass().getName(), "Got to play()!");
Notification note=new Notification(R.drawable.stat_notify_chat,
"Can you hear the music?",
System.currentTimeMillis());
Intent i = new Intent(TiApplication.getInstance().getApplicationContext(),TiApplication.getInstance().getRootOrCurrentActivity().getClass());
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pi=PendingIntent.getActivity(this, 0,
i, 0);
note.setLatestEventInfo(this, "Fake Player",
"Now Playing: \"Ummmm, Nothing\"",
pi);
note.flags|=Notification.FLAG_NO_CLEAR;
startForeground(1337, note);
}
private String getPath(String url) {
String fullUrl = url;
if (!fullUrl.contains("://") && !fullUrl.startsWith("/")) {
fullUrl = new TiUrl(url).baseUrl + fullUrl;
}
if (fullUrl.startsWith(TiC.URL_APP_PREFIX)) {
fullUrl = fullUrl.replaceAll("app:/", "Resources");
} else if (fullUrl.startsWith(TiC.URL_ANDROID_ASSET_RESOURCES)) {
fullUrl = fullUrl.replaceAll("file:///android_asset/", "");
}
return fullUrl;
}
@Override
protected ServiceProxy createProxy(Intent intent)
{
int lastSlash = jsFile.lastIndexOf('/');
String baseUrl = jsFile.substring(0, lastSlash+1);
if (baseUrl.length() == 0) {
baseUrl = null;
}
ServiceProxy proxy = new ServiceProxy(this, intent, proxyCounter.incrementAndGet());
return proxy;
}
}
Very much of this is copy/pasted from various sources on the internet, and there are remnants of that for the purposes of test, try not to mind those.
Thanks,
-John Louderback