From 90658f7dd7f991fb010a2be893e249fed3336009 Mon Sep 17 00:00:00 2001 From: bobatsar Date: Fri, 20 May 2016 17:13:13 +0200 Subject: [PATCH 1/2] load an url in the webview from python code --- .../src/org/kivy/android/PythonActivity.java | 25 ++++++++++++++++--- .../build/templates/WebViewLoader.tmpl.java | 9 +++---- pythonforandroid/toolchain.py | 7 ------ testapps/testapp_flask/main.py | 10 +++++++- testapps/testapp_flask/templates/index.html | 14 +++++++++++ 5 files changed, 47 insertions(+), 18 deletions(-) diff --git a/pythonforandroid/bootstraps/webview/build/src/org/kivy/android/PythonActivity.java b/pythonforandroid/bootstraps/webview/build/src/org/kivy/android/PythonActivity.java index ba00ab36f2..48948f4ba3 100644 --- a/pythonforandroid/bootstraps/webview/build/src/org/kivy/android/PythonActivity.java +++ b/pythonforandroid/bootstraps/webview/build/src/org/kivy/android/PythonActivity.java @@ -94,7 +94,7 @@ protected void onCreate(Bundle savedInstanceState) { Log.v("Python", "Device: " + android.os.Build.DEVICE); Log.v("Python", "Model: " + android.os.Build.MODEL); super.onCreate(savedInstanceState); - + PythonActivity.initialize(); // Load shared libraries @@ -161,7 +161,7 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) { PythonActivity.nativeSetEnv("ANDROID_ENTRYPOINT", "main.pyo"); PythonActivity.nativeSetEnv("PYTHONHOME", mFilesDirectory); PythonActivity.nativeSetEnv("PYTHONPATH", mFilesDirectory + ":" + mFilesDirectory + "/lib"); - + try { Log.v(TAG, "Access to our meta-data..."); this.mMetaData = this.mActivity.getPackageManager().getApplicationInfo( @@ -173,7 +173,7 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) { } } catch (PackageManager.NameNotFoundException e) { } - + final Thread pythonThread = new Thread(new PythonMain(), "PythonThread"); PythonActivity.mPythonThread = pythonThread; pythonThread.start(); @@ -182,7 +182,7 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) { wvThread.start(); } - + public void loadLibraries() { PythonUtil.loadLibraries(getFilesDir()); } @@ -276,6 +276,23 @@ public void unpackData(final String resource, File target) { } } + public static void loadUrl(String url) { + class LoadUrl implements Runnable { + private String mUrl; + + public LoadUrl(String url) { + mUrl = url; + } + + public void run() { + mWebView.loadUrl(mUrl); + } + } + + Log.i(TAG, "Opening URL: " + url); + mActivity.runOnUiThread(new LoadUrl(url)); + } + public static ViewGroup getLayout() { return mLayout; } diff --git a/pythonforandroid/bootstraps/webview/build/templates/WebViewLoader.tmpl.java b/pythonforandroid/bootstraps/webview/build/templates/WebViewLoader.tmpl.java index df6578bdee..fb2583654a 100644 --- a/pythonforandroid/bootstraps/webview/build/templates/WebViewLoader.tmpl.java +++ b/pythonforandroid/bootstraps/webview/build/templates/WebViewLoader.tmpl.java @@ -16,22 +16,21 @@ public class WebViewLoader { private static final String TAG = "WebViewLoader"; public static void testConnection() { - + while (true) { if (WebViewLoader.pingHost("localhost", {{ args.port }}, 100)) { Log.v(TAG, "Successfully pinged localhost:{{ args.port }}"); Handler mainHandler = new Handler(PythonActivity.mActivity.getMainLooper()); - Runnable myRunnable = new Runnable() { @Override public void run() { - PythonActivity.mActivity.mWebView.loadUrl("http://127.0.0.1:{{ args.port }}/"); + PythonActivity.mActivity.loadUrl("http://127.0.0.1:{{ args.port }}/"); Log.v(TAG, "Loaded webserver in webview"); } }; mainHandler.post(myRunnable); break; - + } else { Log.v(TAG, "Could not ping localhost:{{ args.port }}"); try { @@ -55,5 +54,3 @@ public static boolean pingHost(String host, int port, int timeout) { } } } - - diff --git a/pythonforandroid/toolchain.py b/pythonforandroid/toolchain.py index d457be849e..0a48c3f0d1 100755 --- a/pythonforandroid/toolchain.py +++ b/pythonforandroid/toolchain.py @@ -118,13 +118,6 @@ def build_dist_from_args(ctx, dist, args): ctx.recipe_build_order = build_order ctx.python_modules = python_modules - if python_modules and hasattr(sys, 'real_prefix'): - error('virtualenv is needed to install pure-Python modules, but') - error('virtualenv does not support nesting, and you are running') - error('python-for-android in one. Please run p4a outside of a') - error('virtualenv instead.') - exit(1) - info('The selected bootstrap is {}'.format(bs.name)) info_main('# Creating dist with {} bootstrap'.format(bs.name)) bs.distribution = dist diff --git a/testapps/testapp_flask/main.py b/testapps/testapp_flask/main.py index cf0c69c83f..f9d0feff60 100644 --- a/testapps/testapp_flask/main.py +++ b/testapps/testapp_flask/main.py @@ -61,6 +61,14 @@ def vibrate(): vibrator.vibrate(float(args['time']) * 1000) print('vibrated') +@app.route('/loadUrl') +def loadUrl(): + args = request.args + if 'url' not in args: + print('ERROR: asked to open an url but without url argument') + print('asked to open url', args['url']) + activity.loadUrl(args['url']) + @app.route('/orientation') def orientation(): args = request.args @@ -69,7 +77,7 @@ def orientation(): direction = args['dir'] if direction not in ('horizontal', 'vertical'): print('ERROR: asked to orient to neither horizontal nor vertical') - + if direction == 'horizontal': activity.setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) diff --git a/testapps/testapp_flask/templates/index.html b/testapps/testapp_flask/templates/index.html index 08750f6154..78c38b3eaa 100644 --- a/testapps/testapp_flask/templates/index.html +++ b/testapps/testapp_flask/templates/index.html @@ -24,6 +24,20 @@

Page one

} + + + + + From a4a3f8a16c5179ccc317e7faa225dfe42b055fdf Mon Sep 17 00:00:00 2001 From: bobatsar Date: Fri, 20 May 2016 17:31:23 +0200 Subject: [PATCH 2/2] kill python thread on exit and handle back button --- .../src/org/kivy/android/PythonActivity.java | 31 ++++++++++++++++++- pythonforandroid/toolchain.py | 7 +++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/pythonforandroid/bootstraps/webview/build/src/org/kivy/android/PythonActivity.java b/pythonforandroid/bootstraps/webview/build/src/org/kivy/android/PythonActivity.java index 48948f4ba3..efc6043f3a 100644 --- a/pythonforandroid/bootstraps/webview/build/src/org/kivy/android/PythonActivity.java +++ b/pythonforandroid/bootstraps/webview/build/src/org/kivy/android/PythonActivity.java @@ -180,7 +180,15 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) { final Thread wvThread = new Thread(new WebViewLoaderMain(), "WvThread"); wvThread.start(); + } + @Override + public void onDestroy() { + Log.i("Destroy", "end of app"); + super.onDestroy(); + + // make sure all child threads (python_thread) are stopped + android.os.Process.killProcess(android.os.Process.myPid()); } public void loadLibraries() { @@ -297,6 +305,27 @@ public static ViewGroup getLayout() { return mLayout; } + long lastBackClick = SystemClock.elapsedRealtime(); + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + // Check if the key event was the Back button and if there's history + if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) { + mWebView.goBack(); + return true; + } + // If it wasn't the Back key or there's no web page history, bubble up to the default + // system behavior (probably exit the activity) + if (SystemClock.elapsedRealtime() - lastBackClick > 2000){ + lastBackClick = SystemClock.elapsedRealtime(); + Toast.makeText(this, "Click again to close the app", + Toast.LENGTH_LONG).show(); + return true; + } + + lastBackClick = SystemClock.elapsedRealtime(); + return super.onKeyDown(keyCode, event); + } + //---------------------------------------------------------------------------- // Listener interface for onNewIntent @@ -367,7 +396,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent intent) } } - public static void start_service(String serviceTitle, String serviceDescription, + public static void start_service(String serviceTitle, String serviceDescription, String pythonServiceArgument) { Intent serviceIntent = new Intent(PythonActivity.mActivity, PythonService.class); String argument = PythonActivity.mActivity.getFilesDir().getAbsolutePath(); diff --git a/pythonforandroid/toolchain.py b/pythonforandroid/toolchain.py index 0a48c3f0d1..d457be849e 100755 --- a/pythonforandroid/toolchain.py +++ b/pythonforandroid/toolchain.py @@ -118,6 +118,13 @@ def build_dist_from_args(ctx, dist, args): ctx.recipe_build_order = build_order ctx.python_modules = python_modules + if python_modules and hasattr(sys, 'real_prefix'): + error('virtualenv is needed to install pure-Python modules, but') + error('virtualenv does not support nesting, and you are running') + error('python-for-android in one. Please run p4a outside of a') + error('virtualenv instead.') + exit(1) + info('The selected bootstrap is {}'.format(bs.name)) info_main('# Creating dist with {} bootstrap'.format(bs.name)) bs.distribution = dist