Skip to content

Commit bfc0bb3

Browse files
committed
refactor kivy android java classes
1 parent 7b16332 commit bfc0bb3

File tree

4 files changed

+249
-258
lines changed

4 files changed

+249
-258
lines changed
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
package org.kivy.android;
2+
3+
import android.content.Context;
4+
import android.content.pm.PackageInfo;
5+
import android.content.pm.PackageManager;
6+
import android.content.res.AssetManager;
7+
import android.util.Log;
8+
9+
import org.kamranzafar.jtar.TarEntry;
10+
import org.kamranzafar.jtar.TarInputStream;
11+
12+
import java.io.BufferedInputStream;
13+
import java.io.BufferedOutputStream;
14+
import java.io.File;
15+
import java.io.FileInputStream;
16+
import java.io.FileNotFoundException;
17+
import java.io.FileOutputStream;
18+
import java.io.IOException;
19+
import java.io.InputStream;
20+
import java.io.OutputStream;
21+
import java.util.zip.GZIPInputStream;
22+
23+
public class AssetExtract {
24+
private static String TAG = AssetExtract.class.getSimpleName();
25+
26+
/**
27+
* @param parent File or directory to delete recursively
28+
*/
29+
public static void recursiveDelete(File parent) {
30+
if (parent.isDirectory()) {
31+
for (File child : parent.listFiles()) {
32+
recursiveDelete(child);
33+
}
34+
}
35+
parent.delete();
36+
}
37+
38+
public static void extractAsset(Context ctx, String assetName, File target) {
39+
Log.v(TAG, "Extract asset " + assetName + " to " + target.getAbsolutePath());
40+
41+
// The version of data in memory and on disk.
42+
String packaged_version;
43+
String disk_version;
44+
45+
try {
46+
PackageManager manager = ctx.getPackageManager();
47+
PackageInfo info = manager.getPackageInfo(ctx.getPackageName(), 0);
48+
packaged_version = info.versionName;
49+
50+
Log.v(TAG, "Data version is " + packaged_version);
51+
} catch (PackageManager.NameNotFoundException e) {
52+
packaged_version = null;
53+
}
54+
// If no packaged data version, no unpacking is necessary.
55+
if (packaged_version == null) {
56+
Log.w(TAG, "Data version not found");
57+
return;
58+
}
59+
60+
// Check the current disk version, if any.
61+
String filesDir = target.getAbsolutePath();
62+
String disk_version_fn = filesDir + "/" + assetName + ".version";
63+
64+
try {
65+
byte buf[] = new byte[64];
66+
FileInputStream is = new FileInputStream(disk_version_fn);
67+
int len = is.read(buf);
68+
disk_version = new String(buf, 0, len);
69+
is.close();
70+
} catch (Exception e) {
71+
disk_version = "";
72+
}
73+
74+
if (packaged_version.equals(disk_version)) {
75+
Log.v(TAG, "Disk data version equals packaged data version.");
76+
return;
77+
}
78+
79+
recursiveDelete(target);
80+
target.mkdirs();
81+
82+
if (!extractTar(ctx.getAssets(), assetName, target.getAbsolutePath())) {
83+
Log.e(TAG, "Could not extract " + assetName + " data.");
84+
}
85+
86+
try {
87+
// Write .nomedia.
88+
new File(target, ".nomedia").createNewFile();
89+
90+
// Write version file.
91+
FileOutputStream os = new FileOutputStream(disk_version_fn);
92+
os.write(packaged_version.getBytes());
93+
os.close();
94+
} catch (Exception ex) {
95+
Log.w(TAG, ex);
96+
}
97+
}
98+
99+
public static boolean extractTar(AssetManager assets, String assetName, String target) {
100+
byte buf[] = new byte[1024 * 1024];
101+
102+
InputStream assetStream = null;
103+
TarInputStream tis = null;
104+
105+
try {
106+
assetStream = assets.open(assetName, AssetManager.ACCESS_STREAMING);
107+
tis = new TarInputStream(new BufferedInputStream(
108+
new GZIPInputStream(new BufferedInputStream(assetStream,
109+
8192)), 8192));
110+
} catch (IOException e) {
111+
Log.e(TAG, "opening up extract tar", e);
112+
return false;
113+
}
114+
115+
while (true) {
116+
TarEntry entry = null;
117+
118+
try {
119+
entry = tis.getNextEntry();
120+
} catch (java.io.IOException e) {
121+
Log.e(TAG, "extracting tar", e);
122+
return false;
123+
}
124+
125+
if (entry == null) {
126+
break;
127+
}
128+
129+
Log.v(TAG, "extracting " + entry.getName());
130+
131+
if (entry.isDirectory()) {
132+
133+
try {
134+
new File(target + "/" + entry.getName()).mkdirs();
135+
} catch (SecurityException e) {
136+
Log.e(TAG, "extracting tar", e);
137+
}
138+
139+
continue;
140+
}
141+
142+
OutputStream out = null;
143+
String path = target + "/" + entry.getName();
144+
145+
try {
146+
out = new BufferedOutputStream(new FileOutputStream(path), 8192);
147+
} catch (FileNotFoundException e) {
148+
Log.e(TAG, "extracting tar", e);
149+
} catch (SecurityException e) {
150+
Log.e(TAG, "extracting tar", e);
151+
}
152+
153+
if (out == null) {
154+
Log.e(TAG, "could not open " + path);
155+
return false;
156+
}
157+
158+
try {
159+
while (true) {
160+
int len = tis.read(buf);
161+
162+
if (len == -1) {
163+
break;
164+
}
165+
166+
out.write(buf, 0, len);
167+
}
168+
169+
out.flush();
170+
out.close();
171+
} catch (java.io.IOException e) {
172+
Log.e(TAG, "extracting zip", e);
173+
return false;
174+
}
175+
}
176+
177+
try {
178+
tis.close();
179+
assetStream.close();
180+
} catch (IOException e) {
181+
// pass
182+
}
183+
184+
return true;
185+
}
186+
}

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

Lines changed: 35 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,20 @@
22

33
import android.app.Service;
44
import android.content.Intent;
5-
import android.content.pm.PackageInfo;
6-
import android.content.pm.PackageManager;
75
import android.os.Bundle;
86
import android.os.IBinder;
97
import android.os.Process;
108
import android.util.Log;
119

12-
import org.renpy.android.AssetExtract;
13-
14-
import java.io.File;
15-
import java.io.FileInputStream;
16-
import java.io.FileOutputStream;
17-
1810
public class PythonService extends Service implements Runnable {
19-
private static String TAG = "PythonService";
11+
private static String TAG = PythonService.class.getSimpleName();
12+
13+
public static PythonService mService = null;
14+
/**
15+
* Intent that started the service
16+
*/
17+
private Intent startIntent = null;
2018

21-
// Thread for Python code
2219
private Thread pythonThread = null;
2320

2421
// Python environment variables
@@ -28,47 +25,44 @@ public class PythonService extends Service implements Runnable {
2825
private String pythonHome;
2926
private String pythonPath;
3027
private String serviceEntrypoint;
31-
32-
// Argument to pass to Python code,
3328
private String pythonServiceArgument;
34-
public static PythonService mService = null;
35-
private Intent startIntent = null;
3629

3730
private boolean autoRestartService = false;
3831

3932
public void setAutoRestartService(boolean restart) {
4033
autoRestartService = restart;
4134
}
4235

43-
public boolean canDisplayNotification() {
44-
return true;
45-
}
46-
47-
public int startType() {
48-
return START_NOT_STICKY;
49-
}
50-
36+
/**
37+
* {@inheritDoc}
38+
*/
5139
@Override
52-
public IBinder onBind(Intent arg0) {
40+
public IBinder onBind(Intent intent) {
5341
return null;
5442
}
5543

44+
/**
45+
* {@inheritDoc}
46+
*/
5647
@Override
5748
public void onCreate() {
5849
Log.v(TAG, "Device: " + android.os.Build.DEVICE);
5950
Log.v(TAG, "Model: " + android.os.Build.MODEL);
60-
unpackData("private", getFilesDir());
51+
AssetExtract.extractAsset(getApplicationContext(), "private.mp3", getFilesDir());
6152
super.onCreate();
6253
}
6354

55+
/**
56+
* {@inheritDoc}
57+
*/
6458
@Override
6559
public int onStartCommand(Intent intent, int flags, int startId) {
6660
if (pythonThread != null) {
6761
Log.v(TAG, "Service exists, do not start again");
6862
return START_NOT_STICKY;
6963
}
70-
7164
startIntent = intent;
65+
7266
Bundle extras = intent.getExtras();
7367
androidPrivate = extras.getString("androidPrivate");
7468
androidArgument = extras.getString("androidArgument");
@@ -78,6 +72,7 @@ public int onStartCommand(Intent intent, int flags, int startId) {
7872
pythonPath = extras.getString("pythonPath");
7973
pythonServiceArgument = extras.getString("pythonServiceArgument");
8074

75+
Log.v(TAG, "Starting Python thread");
8176
pythonThread = new Thread(this);
8277
pythonThread.start();
8378

@@ -104,6 +99,9 @@ protected void doStartForeground(Bundle extras) {
10499
startForeground(1, notification);
105100
}
106101

102+
/**
103+
* {@inheritDoc}
104+
*/
107105
@Override
108106
public void onDestroy() {
109107
super.onDestroy();
@@ -115,6 +113,9 @@ public void onDestroy() {
115113
Process.killProcess(Process.myPid());
116114
}
117115

116+
/**
117+
* {@inheritDoc}
118+
*/
118119
@Override
119120
public void run() {
120121
PythonUtil.loadLibraries(getFilesDir());
@@ -124,80 +125,15 @@ public void run() {
124125
stopSelf();
125126
}
126127

127-
public void recursiveDelete(File f) {
128-
if (f.isDirectory()) {
129-
for (File r : f.listFiles()) {
130-
recursiveDelete(r);
131-
}
132-
}
133-
f.delete();
134-
}
135-
136-
public void unpackData(final String resource, File target) {
137-
138-
Log.v(TAG, "UNPACKING!!! " + resource + " " + target.getName());
139-
140-
// The version of data in memory and on disk.
141-
String data_version = null;
142-
String disk_version = null;
143-
144-
try {
145-
PackageManager manager = this.getPackageManager();
146-
PackageInfo info = manager.getPackageInfo(this.getPackageName(), 0);
147-
data_version = info.versionName;
148-
149-
Log.v(TAG, "Data version is " + data_version);
150-
} catch (PackageManager.NameNotFoundException e) {
151-
Log.w(TAG, "Data version not found of " + resource + " data.");
152-
}
153-
154-
// If no version, no unpacking is necessary.
155-
if (data_version == null) {
156-
return;
157-
}
158-
159-
// Check the current disk version, if any.
160-
String filesDir = target.getAbsolutePath();
161-
String disk_version_fn = filesDir + "/" + resource + ".version";
162-
163-
try {
164-
byte buf[] = new byte[64];
165-
FileInputStream is = new FileInputStream(disk_version_fn);
166-
int len = is.read(buf);
167-
disk_version = new String(buf, 0, len);
168-
is.close();
169-
} catch (Exception e) {
170-
disk_version = "";
171-
}
172-
173-
// If the disk data is out of date, extract it and write the version
174-
// file.
175-
if (!data_version.equals(disk_version)) {
176-
Log.v(TAG, "Extracting " + resource + " assets.");
177-
178-
recursiveDelete(target);
179-
target.mkdirs();
180-
181-
AssetExtract ae = new AssetExtract(this);
182-
if (!ae.extractTar(resource + ".mp3", target.getAbsolutePath())) {
183-
Log.e(TAG, "Could not extract " + resource + " data.");
184-
}
185-
186-
try {
187-
// Write .nomedia.
188-
new File(target, ".nomedia").createNewFile();
189-
190-
// Write version file.
191-
FileOutputStream os = new FileOutputStream(disk_version_fn);
192-
os.write(data_version.getBytes());
193-
os.close();
194-
} catch (Exception e) {
195-
Log.w("python", e);
196-
}
197-
}
198-
}
199-
200-
// Native part
128+
/**
129+
* @param androidPrivate Directory for private files
130+
* @param androidArgument Android path
131+
* @param serviceEntrypoint Python file to execute first
132+
* @param pythonName Python name
133+
* @param pythonHome Python home
134+
* @param pythonPath Python path
135+
* @param pythonServiceArgument Argument to pass to Python code
136+
*/
201137
public static native void nativeStart(String androidPrivate,
202138
String androidArgument, String serviceEntrypoint,
203139
String pythonName, String pythonHome, String pythonPath,

0 commit comments

Comments
 (0)