Skip to content

Commit dd68e61

Browse files
authored
Merge pull request kivy#845 from brussee/service_only
Improve service_only bootstrap
2 parents aad5a67 + 83394c7 commit dd68e61

File tree

5 files changed

+63
-47
lines changed

5 files changed

+63
-47
lines changed

pythonforandroid/bootstraps/service_only/__init__.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
from pythonforandroid.toolchain import Bootstrap, shprint, current_directory, info, warning, ArchARM, info_main
2-
from os.path import join, exists, curdir, abspath
3-
from os import walk
41
import glob
2+
from os import walk
3+
from os.path import join, exists, curdir, abspath
54
import sh
5+
from pythonforandroid.toolchain import Bootstrap, shprint, current_directory, info, warning, ArchARM, info_main
6+
67

78
class ServiceOnlyBootstrap(Bootstrap):
9+
810
name = 'service_only'
911

1012
recipe_depends = ['genericndkbuild', ('python2', 'python3crystax')]
@@ -62,7 +64,7 @@ def run_distribute(self):
6264
# AND: Copylibs stuff should go here
6365
if exists(join('libs', arch.arch, 'libpymodules.so')):
6466
shprint(sh.mv, join('libs', arch.arch, 'libpymodules.so'), 'private/')
65-
shprint(sh.cp, join('python-install', 'include' , 'python2.7', 'pyconfig.h'), join('private', 'include', 'python2.7/'))
67+
shprint(sh.cp, join('python-install', 'include', 'python2.7', 'pyconfig.h'), join('private', 'include', 'python2.7/'))
6668

6769
info('Removing some unwanted files')
6870
shprint(sh.rm, '-f', join('private', 'lib', 'libpython2.7.so'))
@@ -118,4 +120,5 @@ def run_distribute(self):
118120
self.fry_eggs(site_packages_dir)
119121
super(ServiceOnlyBootstrap, self).run_distribute()
120122

121-
bootstrap = ServiceOnlyBootstrap()
123+
124+
bootstrap = ServiceOnlyBootstrap()

pythonforandroid/bootstraps/service_only/build/jni/src/start.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ int main(int argc, char *argv[]) {
279279
}
280280

281281
JNIEXPORT void JNICALL Java_org_kivy_android_PythonService_nativeStart(
282-
JNIEnv *env, jobject thiz, jstring j_android_private,
282+
JNIEnv *env, jobject j_this, jstring j_android_private,
283283
jstring j_android_argument, jstring j_service_entrypoint,
284284
jstring j_python_name, jstring j_python_home, jstring j_python_path,
285285
jstring j_arg) {
@@ -296,7 +296,8 @@ JNIEXPORT void JNICALL Java_org_kivy_android_PythonService_nativeStart(
296296
(*env)->GetStringUTFChars(env, j_python_home, &iscopy);
297297
const char *python_path =
298298
(*env)->GetStringUTFChars(env, j_python_path, &iscopy);
299-
const char *arg = (*env)->GetStringUTFChars(env, j_arg, &iscopy);
299+
const char *arg =
300+
(*env)->GetStringUTFChars(env, j_arg, &iscopy);
300301

301302
setenv("ANDROID_PRIVATE", android_private, 1);
302303
setenv("ANDROID_ARGUMENT", android_argument, 1);

pythonforandroid/bootstraps/service_only/build/src/org/kivy/android/PythonService.java

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
11
package org.kivy.android;
22

3-
import android.app.Activity;
43
import android.app.PendingIntent;
54
import android.app.Service;
65
import android.content.Context;
76
import android.content.Intent;
7+
import android.content.pm.ApplicationInfo;
88
import android.os.Bundle;
9-
import android.os.IBinder;
109
import android.os.Process;
1110
import android.support.v4.app.NotificationCompat;
1211
import android.util.Log;
1312

14-
public class PythonService extends Service implements Runnable {
13+
public abstract class PythonService extends Service implements Runnable {
1514
private static String TAG = PythonService.class.getSimpleName();
1615

17-
public static PythonService mService = null;
1816
/**
1917
* Intent that started the service
2018
*/
@@ -31,26 +29,16 @@ public class PythonService extends Service implements Runnable {
3129
private String serviceEntrypoint;
3230
private String pythonServiceArgument;
3331

34-
private boolean autoRestartService = false;
35-
36-
public void setAutoRestartService(boolean restart) {
37-
autoRestartService = restart;
38-
}
39-
40-
public boolean canDisplayNotification() {
41-
return true;
32+
public int getStartType() {
33+
return START_NOT_STICKY;
4234
}
4335

44-
public int startType() {
45-
return START_NOT_STICKY;
36+
public boolean getStartForeground() {
37+
return false;
4638
}
4739

48-
/**
49-
* {@inheritDoc}
50-
*/
51-
@Override
52-
public IBinder onBind(Intent intent) {
53-
return null;
40+
public boolean getAutoRestart() {
41+
return false;
5442
}
5543

5644
/**
@@ -88,28 +76,30 @@ public int onStartCommand(Intent intent, int flags, int startId) {
8876
pythonThread = new Thread(this);
8977
pythonThread.start();
9078

91-
if (canDisplayNotification()) {
79+
if (getStartForeground()) {
9280
doStartForeground(extras);
9381
}
9482

95-
return startType();
83+
return getStartType();
9684
}
9785

9886
protected void doStartForeground(Bundle extras) {
99-
String serviceTitle = extras.getString("serviceTitle");
100-
String serviceDescription = extras.getString("serviceDescription");
87+
Context appContext = getApplicationContext();
88+
ApplicationInfo appInfo = appContext.getApplicationInfo();
10189

102-
Context context = getApplicationContext();
90+
String serviceTitle = extras.getString("serviceTitle", TAG);
91+
String serviceDescription = extras.getString("serviceDescription", "");
92+
int serviceIconId = extras.getInt("serviceIconId", appInfo.icon);
10393

10494
NotificationCompat.Builder builder =
10595
new NotificationCompat.Builder(this)
106-
.setSmallIcon(context.getApplicationInfo().icon)
96+
.setSmallIcon(serviceIconId)
10797
.setContentTitle(serviceTitle)
10898
.setContentText(serviceDescription);
10999

110100
int NOTIFICATION_ID = 1;
111101

112-
Intent targetIntent = new Intent(this, Activity.class);
102+
Intent targetIntent = new Intent(this, MainActivity.class);
113103
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, targetIntent, PendingIntent.FLAG_UPDATE_CURRENT);
114104
builder.setContentIntent(contentIntent);
115105

@@ -123,7 +113,7 @@ protected void doStartForeground(Bundle extras) {
123113
public void onDestroy() {
124114
super.onDestroy();
125115
pythonThread = null;
126-
if (autoRestartService && startIntent != null) {
116+
if (getAutoRestart() && startIntent != null) {
127117
Log.v(TAG, "Service restart requested");
128118
startService(startIntent);
129119
}
@@ -136,9 +126,8 @@ public void onDestroy() {
136126
@Override
137127
public void run() {
138128
PythonUtil.loadLibraries(getFilesDir());
139-
mService = this;
140-
nativeStart(androidPrivate, androidArgument, serviceEntrypoint,
141-
pythonName, pythonHome, pythonPath, pythonServiceArgument);
129+
nativeStart(androidPrivate, androidArgument, serviceEntrypoint, pythonName, pythonHome,
130+
pythonPath, pythonServiceArgument);
142131
stopSelf();
143132
}
144133

@@ -151,8 +140,8 @@ public void run() {
151140
* @param pythonPath Python path
152141
* @param pythonServiceArgument Argument to pass to Python code
153142
*/
154-
public static native void nativeStart(String androidPrivate,
155-
String androidArgument, String serviceEntrypoint,
156-
String pythonName, String pythonHome, String pythonPath,
143+
public static native void nativeStart(String androidPrivate, String androidArgument,
144+
String serviceEntrypoint, String pythonName,
145+
String pythonHome, String pythonPath,
157146
String pythonServiceArgument);
158147
}

pythonforandroid/bootstraps/service_only/build/templates/Service.tmpl.java

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,29 @@
44
import android.content.Context;
55
import org.kivy.android.PythonService;
66

7-
87
public class Service{{ name|capitalize }} extends PythonService {
8+
/**
9+
* Binder given to clients
10+
*/
11+
private final IBinder mBinder = new Service{{ name|capitalize }}Binder();
12+
913
{% if sticky %}
1014
/**
1115
* {@inheritDoc}
1216
*/
1317
@Override
14-
public int startType() {
18+
public int getStartType() {
1519
return START_STICKY;
1620
}
1721
{% endif %}
1822

19-
{% if not foreground %}
23+
{% if foreground %}
2024
/**
2125
* {@inheritDoc}
2226
*/
2327
@Override
24-
public boolean canDisplayNotification() {
25-
return false;
28+
public boolean getStartForeground() {
29+
return true;
2630
}
2731
{% endif %}
2832

@@ -46,4 +50,22 @@ public static void stop(Context ctx) {
4650
ctx.stopService(intent);
4751
}
4852

53+
/**
54+
* {@inheritDoc}
55+
*/
56+
@Override
57+
public IBinder onBind(Intent intent) {
58+
return mBinder;
59+
}
60+
61+
/**
62+
* Class used for the client Binder. Because we know this service always
63+
* runs in the same process as its clients, we don't need to deal with IPC.
64+
*/
65+
public class Service{{ name|capitalize }}Binder extends Binder {
66+
Service{{ name|capitalize }} getService() {
67+
// Return this instance of Service{{ name|capitalize }} so clients can call public methods
68+
return Service{{ name|capitalize }}.this;
69+
}
70+
}
4971
}

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ def recursively_include(results, directory, patterns):
3434
'*.mk', '*.jam', ])
3535
recursively_include(package_data, 'pythonforandroid/bootstraps',
3636
['*.properties', '*.xml', '*.java', '*.tmpl', '*.txt', '*.png',
37-
'*.mk', '*.c', '*.h', '*.py', '*.sh', '*.jpg', '*.aidl', ])
37+
'*.mk', '*.c', '*.h', '*.py', '*.sh', '*.jpg', '*.aidl',
38+
'*.gradle', ])
3839
recursively_include(package_data, 'pythonforandroid/bootstraps',
3940
['sdl-config', ])
4041
recursively_include(package_data, 'pythonforandroid/bootstraps/webview',

0 commit comments

Comments
 (0)