From 86f738d9471e6ff953b70f87466dd0a7dcd27105 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Thu, 24 Mar 2022 13:03:28 +0000 Subject: [PATCH] Actual working app loader - albeit slow --- .../banglejs/AppsManagementActivity.java | 57 ++++++++++++++++--- .../banglejs/BangleJSDeviceSupport.java | 37 ++++++++++++ 2 files changed, 85 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/AppsManagementActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/AppsManagementActivity.java index 9b4711147..75cbbd010 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/AppsManagementActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/banglejs/AppsManagementActivity.java @@ -10,6 +10,7 @@ import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.webkit.JavascriptInterface; +import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.AdapterView; @@ -28,12 +29,15 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; + import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; +import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.devices.banglejs.BangleJSDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; @@ -41,10 +45,31 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB; public class AppsManagementActivity extends AbstractGBActivity { private static final Logger LOG = LoggerFactory.getLogger(AppsManagementActivity.class); + private final BroadcastReceiver commandReceiver; + private WebView webView; private GBDevice mGBDevice; private DeviceCoordinator mCoordinator; + public AppsManagementActivity() { + IntentFilter commandFilter = new IntentFilter(); + commandFilter.addAction(BangleJSDeviceSupport.BANGLEJS_COMMAND_RX); + commandReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + switch (intent.getAction()) { + case BangleJSDeviceSupport.BANGLEJS_COMMAND_RX: { + String data = String.valueOf(intent.getExtras().get("DATA")); + LOG.info("WebView TX: " + data); + bangleRxData(data); + break; + } + } + } + }; + LocalBroadcastManager.getInstance(GBApplication.getContext()).registerReceiver(commandReceiver, commandFilter); + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -86,7 +111,6 @@ public class AppsManagementActivity extends AbstractGBActivity { } }; - public class WebViewInterface { Context mContext; @@ -94,16 +118,17 @@ public class AppsManagementActivity extends AbstractGBActivity { mContext = c; } + /// Called from the WebView when data needs to be sent to the Bangle @JavascriptInterface public void bangleTx(String data) { LOG.info("WebView RX: " + data); - bangleRx("Hello world"); + bangleTxData(data); } } - // Called when data received from Bangle.js - public void bangleRx(String data) { + // Called when data received from Bangle.js - push data to the WebView + public void bangleRxData(String data) { JSONArray s = new JSONArray(); s.put(data); String ss = s.toString(); @@ -114,25 +139,39 @@ public class AppsManagementActivity extends AbstractGBActivity { public void run() { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { webView.evaluateJavascript(js, null); - } - else { + } else { webView.loadUrl("javascript: "+js); } } }); } + // Called to send data to Bangle.js + public void bangleTxData(String data) { + Intent intent = new Intent(BangleJSDeviceSupport.BANGLEJS_COMMAND_TX); + intent.putExtra("DATA", data); + LocalBroadcastManager.getInstance(this).sendBroadcast(intent); + } + private void initViews() { //https://stackoverflow.com/questions/4325639/android-calling-javascript-functions-in-webview webView = findViewById(R.id.webview); webView.setWebViewClient(new WebViewClient()); - webView.getSettings().setJavaScriptEnabled(true); + WebSettings settings = webView.getSettings(); + settings.setJavaScriptEnabled(true); + settings.setDatabaseEnabled(true); + settings.setDomStorageEnabled(true); + settings.setUseWideViewPort(true); + settings.setLoadWithOverviewMode(true); + String databasePath = this.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath(); + settings.setDatabasePath(databasePath); webView.addJavascriptInterface(new WebViewInterface(this), "Android"); - webView.loadUrl("https://www.pur3.co.uk/tmp/android.html"); + webView.setWebContentsDebuggingEnabled(true); // FIXME + webView.loadUrl("https://banglejs.com/apps/android.html"); webView.setWebViewClient(new WebViewClient(){ public void onPageFinished(WebView view, String weburl){ - webView.loadUrl("javascript:showToast('WebView in Espruino')"); + //webView.loadUrl("javascript:showToast('WebView in Espruino')"); } }); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java index a03cf9446..d3f6b4ac1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java @@ -18,8 +18,10 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.banglejs; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; @@ -51,6 +53,8 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Iterator; import java.util.SimpleTimeZone; import java.util.UUID; import java.lang.reflect.Field; @@ -66,6 +70,7 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventMusicContr import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventNotificationControl; import nodomain.freeyourgadget.gadgetbridge.devices.banglejs.BangleJSConstants; import nodomain.freeyourgadget.gadgetbridge.devices.banglejs.BangleJSSampleProvider; +import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.NotificationConfiguration; import nodomain.freeyourgadget.gadgetbridge.entities.BangleJSActivitySample; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; @@ -81,6 +86,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest; import nodomain.freeyourgadget.gadgetbridge.util.AlarmUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; @@ -92,6 +98,8 @@ import javax.xml.xpath.XPathFactory; public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport { private static final Logger LOG = LoggerFactory.getLogger(BangleJSDeviceSupport.class); + private final BroadcastReceiver commandReceiver; + private BluetoothGattCharacteristic rxCharacteristic = null; private BluetoothGattCharacteristic txCharacteristic = null; private int mtuSize = 20; @@ -101,9 +109,34 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport { private boolean realtimeStep = false; private int realtimeHRMInterval = 30*60; + public static final String BANGLEJS_COMMAND_TX = "banglejs_command_tx"; + public static final String BANGLEJS_COMMAND_RX = "banglejs_command_rx"; + public BangleJSDeviceSupport() { super(LOG); addSupportedService(BangleJSConstants.UUID_SERVICE_NORDIC_UART); + + IntentFilter commandFilter = new IntentFilter(); + commandFilter.addAction(BANGLEJS_COMMAND_TX); + commandReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + switch (intent.getAction()) { + case BANGLEJS_COMMAND_TX: { + String data = String.valueOf(intent.getExtras().get("DATA")); + try { + TransactionBuilder builder = performInitialized("TX"); + uartTx(builder, data); + builder.queue(getQueue()); + } catch (IOException e) { + GB.toast(getContext(), "Error in TX: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); + } + break; + } + } + } + }; + LocalBroadcastManager.getInstance(GBApplication.getContext()).registerReceiver(commandReceiver, commandFilter); } @Override @@ -362,6 +395,10 @@ public class BangleJSDeviceSupport extends AbstractBTLEDeviceSupport { receivedLine = receivedLine.substring(p+1); handleUartRxLine(line); } + // Send an intent with new data + Intent intent = new Intent(BangleJSDeviceSupport.BANGLEJS_COMMAND_RX); + intent.putExtra("DATA", packetStr); + LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent); } return false; }