Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions pythonforandroid/bootstraps/service_only/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from pythonforandroid.toolchain import Bootstrap, shprint, current_directory, info, warning, ArchARM, info_main
from os.path import join, exists, curdir, abspath
from os import walk
import glob
from os import walk
from os.path import join, exists, curdir, abspath
import sh
from pythonforandroid.toolchain import Bootstrap, shprint, current_directory, info, warning, ArchARM, info_main


class ServiceOnlyBootstrap(Bootstrap):

name = 'service_only'

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

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

bootstrap = ServiceOnlyBootstrap()

bootstrap = ServiceOnlyBootstrap()
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ int main(int argc, char *argv[]) {
}

JNIEXPORT void JNICALL Java_org_kivy_android_PythonService_nativeStart(
JNIEnv *env, jobject thiz, jstring j_android_private,
JNIEnv *env, jobject j_this, jstring j_android_private,
jstring j_android_argument, jstring j_service_entrypoint,
jstring j_python_name, jstring j_python_home, jstring j_python_path,
jstring j_arg) {
Expand All @@ -296,7 +296,8 @@ JNIEXPORT void JNICALL Java_org_kivy_android_PythonService_nativeStart(
(*env)->GetStringUTFChars(env, j_python_home, &iscopy);
const char *python_path =
(*env)->GetStringUTFChars(env, j_python_path, &iscopy);
const char *arg = (*env)->GetStringUTFChars(env, j_arg, &iscopy);
const char *arg =
(*env)->GetStringUTFChars(env, j_arg, &iscopy);

setenv("ANDROID_PRIVATE", android_private, 1);
setenv("ANDROID_ARGUMENT", android_argument, 1);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
package org.kivy.android;

import android.app.Activity;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Process;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

public class PythonService extends Service implements Runnable {
public abstract class PythonService extends Service implements Runnable {
private static String TAG = PythonService.class.getSimpleName();

public static PythonService mService = null;
/**
* Intent that started the service
*/
Expand All @@ -31,26 +29,16 @@ public class PythonService extends Service implements Runnable {
private String serviceEntrypoint;
private String pythonServiceArgument;

private boolean autoRestartService = false;

public void setAutoRestartService(boolean restart) {
autoRestartService = restart;
}

public boolean canDisplayNotification() {
return true;
public int getStartType() {
return START_NOT_STICKY;
}

public int startType() {
return START_NOT_STICKY;
public boolean getStartForeground() {
return false;
}

/**
* {@inheritDoc}
*/
@Override
public IBinder onBind(Intent intent) {
return null;
public boolean getAutoRestart() {
return false;
}

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

if (canDisplayNotification()) {
if (getStartForeground()) {
doStartForeground(extras);
}

return startType();
return getStartType();
}

protected void doStartForeground(Bundle extras) {
String serviceTitle = extras.getString("serviceTitle");
String serviceDescription = extras.getString("serviceDescription");
Context appContext = getApplicationContext();
ApplicationInfo appInfo = appContext.getApplicationInfo();

Context context = getApplicationContext();
String serviceTitle = extras.getString("serviceTitle", TAG);
String serviceDescription = extras.getString("serviceDescription", "");
int serviceIconId = extras.getInt("serviceIconId", appInfo.icon);

NotificationCompat.Builder builder =
new NotificationCompat.Builder(this)
.setSmallIcon(context.getApplicationInfo().icon)
.setSmallIcon(serviceIconId)
.setContentTitle(serviceTitle)
.setContentText(serviceDescription);

int NOTIFICATION_ID = 1;

Intent targetIntent = new Intent(this, Activity.class);
Intent targetIntent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, targetIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIntent);

Expand All @@ -123,7 +113,7 @@ protected void doStartForeground(Bundle extras) {
public void onDestroy() {
super.onDestroy();
pythonThread = null;
if (autoRestartService && startIntent != null) {
if (getAutoRestart() && startIntent != null) {
Log.v(TAG, "Service restart requested");
startService(startIntent);
}
Expand All @@ -136,9 +126,8 @@ public void onDestroy() {
@Override
public void run() {
PythonUtil.loadLibraries(getFilesDir());
mService = this;
nativeStart(androidPrivate, androidArgument, serviceEntrypoint,
pythonName, pythonHome, pythonPath, pythonServiceArgument);
nativeStart(androidPrivate, androidArgument, serviceEntrypoint, pythonName, pythonHome,
pythonPath, pythonServiceArgument);
stopSelf();
}

Expand All @@ -151,8 +140,8 @@ public void run() {
* @param pythonPath Python path
* @param pythonServiceArgument Argument to pass to Python code
*/
public static native void nativeStart(String androidPrivate,
String androidArgument, String serviceEntrypoint,
String pythonName, String pythonHome, String pythonPath,
public static native void nativeStart(String androidPrivate, String androidArgument,
String serviceEntrypoint, String pythonName,
String pythonHome, String pythonPath,
String pythonServiceArgument);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,29 @@
import android.content.Context;
import org.kivy.android.PythonService;


public class Service{{ name|capitalize }} extends PythonService {
/**
* Binder given to clients
*/
private final IBinder mBinder = new Service{{ name|capitalize }}Binder();

{% if sticky %}
/**
* {@inheritDoc}
*/
@Override
public int startType() {
public int getStartType() {
return START_STICKY;
}
{% endif %}

{% if not foreground %}
{% if foreground %}
/**
* {@inheritDoc}
*/
@Override
public boolean canDisplayNotification() {
return false;
public boolean getStartForeground() {
return true;
}
{% endif %}

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

/**
* {@inheritDoc}
*/
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}

/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class Service{{ name|capitalize }}Binder extends Binder {
Service{{ name|capitalize }} getService() {
// Return this instance of Service{{ name|capitalize }} so clients can call public methods
return Service{{ name|capitalize }}.this;
}
}
}
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ def recursively_include(results, directory, patterns):
'*.mk', '*.jam', ])
recursively_include(package_data, 'pythonforandroid/bootstraps',
['*.properties', '*.xml', '*.java', '*.tmpl', '*.txt', '*.png',
'*.mk', '*.c', '*.h', '*.py', '*.sh', '*.jpg', '*.aidl', ])
'*.mk', '*.c', '*.h', '*.py', '*.sh', '*.jpg', '*.aidl',
'*.gradle', ])
recursively_include(package_data, 'pythonforandroid/bootstraps',
['sdl-config', ])
recursively_include(package_data, 'pythonforandroid/bootstraps/webview',
Expand Down