diff --git a/demos/android/.gitignore b/demos/android/.gitignore
index 0718494ec..0d7a3d8a8 100644
--- a/demos/android/.gitignore
+++ b/demos/android/.gitignore
@@ -1,5 +1,6 @@
/build
/captures
+/app/src/main/assets/blockly/msg
.settings
.project
diff --git a/demos/android/README.md b/demos/android/README.md
new file mode 100644
index 000000000..9c63f70b6
--- /dev/null
+++ b/demos/android/README.md
@@ -0,0 +1,45 @@
+# Blockly in an Android WebView
+
+This code demonstrates how to get Blockly running in an Android app by
+embedding it in a WebView.
+
+### BlocklyWebViewFragment
+
+Most of the work is done within the fragment class `BlocklyWebViewFragment`.
+This fragment instantiates the WebView, loads the HTML
+(`assets/blockly/webview.html`), and provides a few helper methods.
+
+### Copying web assets with gradle
+
+This android project copies the necessary files from the main Blockly
+repository (i.e., parent directory). In `app/build.gradle`, note the
+`copyBlocklyWebFiles` task and `preBuild.dependsOn copyBlocklyWebFiles` line.
+
+In your own project, these files can be placed directly in the `assets/blockly`
+directory without the copy step. However, if you do use the copy step, make
+sure you adapt the copy paths appropriately. Additionally, you may want to
+update your `.gitignore` or similar file.
+
+### Loading Block Definitions and Generator functions
+
+The `webview.html` loads the block definitions and generator functions directly
+into the page, without support or coordination with the Android classes. This
+assumes the app will always utilize the same blocks. This does not mean all
+blocks are visible to the user all the time; that is controlled by the toolbox
+and workspace files. This should accommodate almost all applications.
+
+This does mean loading your own block definitions and generators will involve
+editing the HTML, adding you own `<script>` tag, and possibly removing
+the `blocks_compressed.js` if you do not use any standard blocks.
+
+### Connecting a Developer Console
+
+While the console output of the WebView will be visible in the Android log
+(i.e., `logcat`), some times a more intrusive approach is required to isolate
+a problem. For instructions on connecting the WebView to Chrome's Developer
+Tools, see this article:
+
+ https://developers.google.com/web/tools/chrome-devtools/remote-debugging/
+
+The WebView must be visible in the connect device or emulator before the
+WebView will included in the list of available pages to connect to.
\ No newline at end of file
diff --git a/demos/android/app/.gitignore b/demos/android/app/.gitignore
index 796b96d1c..d67f7b424 100644
--- a/demos/android/app/.gitignore
+++ b/demos/android/app/.gitignore
@@ -1 +1,6 @@
/build
+
+# Files copied during build:
+src/main/assets/blockly/blockly_compressed.js
+src/main/assets/blockly/blocks_compressed.js
+src/main/assets/blockly/media
diff --git a/demos/android/app/build.gradle b/demos/android/app/build.gradle
index e80e4cbce..661a3db87 100644
--- a/demos/android/app/build.gradle
+++ b/demos/android/app/build.gradle
@@ -20,6 +20,18 @@ android {
}
}
+task copyBlocklyWebFiles(type: Copy) {
+ from('../../..') {
+ include 'blockly_compressed.js', 'blocks_compressed.js', 'msg/js/**', 'media/**'
+ exclude 'media/test_*'
+ }
+ into project(':app').file('./src/main/assets/blockly')
+}
+
+project.afterEvaluate {
+ preBuild.dependsOn copyBlocklyWebFiles
+}
+
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:27.1.1'
diff --git a/demos/android/app/src/main/assets/blockly/toolbox_standard.js b/demos/android/app/src/main/assets/blockly/toolbox_standard.js
new file mode 100644
index 000000000..77e1a6863
--- /dev/null
+++ b/demos/android/app/src/main/assets/blockly/toolbox_standard.js
@@ -0,0 +1,333 @@
+
+var BLOCKLY_TOOLBOX_XML = BLOCKLY_TOOLBOX_XML || Object.create(null);
+
+/* BEGINNING BLOCKLY_TOOLBOX_XML ASSIGNMENT. DO NOT EDIT. USE BLOCKLY DEVTOOLS. */
+BLOCKLY_TOOLBOX_XML['standard'] =
+// From XML string/file, replace ^\s?(\s*)?(<.*>)$ with \+$1'$2'
+// Tweak first and last line.
+''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ '10'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ '1'
++ ''
++ ''
++ ''
++ ''
++ '10'
++ ''
++ ''
++ ''
++ ''
++ '1'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ '123'
++ ''
++ ''
++ ''
++ ''
++ '1'
++ ''
++ ''
++ ''
++ ''
++ '1'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ '9'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ '45'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ '0'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ '3.1'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ '64'
++ ''
++ ''
++ ''
++ ''
++ '10'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ '50'
++ ''
++ ''
++ ''
++ ''
++ '1'
++ ''
++ ''
++ ''
++ ''
++ '100'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ '1'
++ ''
++ ''
++ ''
++ ''
++ '100'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ 'abc'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ 'text'
++ ''
++ ''
++ ''
++ ''
++ 'abc'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ 'text'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ 'text'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ 'abc'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ 'abc'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ 'abc'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ 'abc'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ '5'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ 'list'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ 'list'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ 'list'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ 'list'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ','
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ '100'
++ ''
++ ''
++ ''
++ ''
++ '50'
++ ''
++ ''
++ ''
++ ''
++ '0'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ '#ff0000'
++ ''
++ ''
++ ''
++ ''
++ '#3333ff'
++ ''
++ ''
++ ''
++ ''
++ '0.5'
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ ''
++ '';
+/* END BLOCKLY_TOOLBOX_XML ASSIGNMENT. DO NOT EDIT. */
diff --git a/demos/android/app/src/main/assets/blockly/webview.html b/demos/android/app/src/main/assets/blockly/webview.html
new file mode 100644
index 000000000..0ecbea2f1
--- /dev/null
+++ b/demos/android/app/src/main/assets/blockly/webview.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/android/app/src/main/java/com/google/blockly/android/webview/BlocklyWebViewFragment.java b/demos/android/app/src/main/java/com/google/blockly/android/webview/BlocklyWebViewFragment.java
new file mode 100644
index 000000000..c9629d2f3
--- /dev/null
+++ b/demos/android/app/src/main/java/com/google/blockly/android/webview/BlocklyWebViewFragment.java
@@ -0,0 +1,37 @@
+package com.google.blockly.android.webview;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+
+/**
+ * This fragments contains and manages the web view that hosts Blockly.
+ */
+public class BlocklyWebViewFragment extends Fragment {
+ protected @Nullable WebView mWebView = null;
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ mWebView = new WebView(inflater.getContext());
+ WebSettings webSettings = mWebView.getSettings();
+ webSettings.setJavaScriptEnabled(true);
+ mWebView.loadUrl("file:///android_asset/blockly/webview.html");
+ return mWebView;
+ }
+
+ // TODO: Method to invoke code generation
+ // TODO: Method to load workspace from string (or InputStream?)
+ // TODO: Method to serialize workspace to string (or OutputStream?)
+ // TODO: Clear / reset workspace
+ // TODO: Load toolbox
+ // TODO: Listener for event JSON
+ // TODO: Method to evaluate JavaScript string in the WebView
+}
diff --git a/demos/android/app/src/main/java/com/google/blockly/android/webview/demo/MainActivity.java b/demos/android/app/src/main/java/com/google/blockly/android/webview/demo/MainActivity.java
index 58cb54d92..ea7bf5659 100644
--- a/demos/android/app/src/main/java/com/google/blockly/android/webview/demo/MainActivity.java
+++ b/demos/android/app/src/main/java/com/google/blockly/android/webview/demo/MainActivity.java
@@ -5,8 +5,11 @@ import android.os.Bundle;
import com.example.blocklywebview.R;
+/**
+ * The primary activity of the demo application. The activity embeds the
+ * {@link com.google.blockly.android.webview.BlocklyWebViewFragment}.
+ */
public class MainActivity extends AppCompatActivity {
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/demos/android/app/src/main/res/layout/activity_main.xml b/demos/android/app/src/main/res/layout/activity_main.xml
index 3dc9926ad..37dc152b0 100644
--- a/demos/android/app/src/main/res/layout/activity_main.xml
+++ b/demos/android/app/src/main/res/layout/activity_main.xml
@@ -7,13 +7,11 @@
android:layout_height="match_parent"
tools:context="com.google.blockly.android.webview.demo.MainActivity">
-
+
\ No newline at end of file