mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2025-01-11 17:41:57 +01:00
Pebble: refactor the background webview
Now native controls seem to work (including datepicker), still the webview is not started upon watchapp start, but when long-pressing each app in the app manager. After the webview is started it will live in the background until device disconnect.
This commit is contained in:
parent
6d02a76328
commit
eaaa940637
@ -7,6 +7,7 @@ import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.webkit.JavascriptInterface;
|
||||
import android.webkit.ValueCallback;
|
||||
import android.webkit.WebView;
|
||||
@ -45,11 +46,64 @@ public class ExternalPebbleJSActivity extends GBActivity {
|
||||
throw new IllegalArgumentException("Must provide a device when invoking this activity");
|
||||
}
|
||||
|
||||
|
||||
setContentView(R.layout.activity_external_pebble_js);
|
||||
|
||||
myWebView = WebViewSingleton.getorInitWebView(this, mGBDevice, appUuid);
|
||||
myWebView.setWillNotDraw(false);
|
||||
myWebView.addJavascriptInterface(new ActivityJSInterface(ExternalPebbleJSActivity.this), "GBActivity");
|
||||
FrameLayout fl = (FrameLayout) findViewById(R.id.webview_placeholder);
|
||||
fl.addView(myWebView);
|
||||
|
||||
WebViewSingleton.getorInitWebView(this, mGBDevice, appUuid);
|
||||
|
||||
myWebView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
|
||||
@Override
|
||||
public void onViewAttachedToWindow(View v) {
|
||||
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
// chromium, enable hardware acceleration
|
||||
v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||
} else {
|
||||
// older android version, disable hardware acceleration
|
||||
v.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||
}
|
||||
|
||||
|
||||
String queryString = "";
|
||||
if (confUri != null) {
|
||||
//getting back with configuration data
|
||||
try {
|
||||
appUuid = UUID.fromString(confUri.getHost());
|
||||
queryString = confUri.getEncodedQuery();
|
||||
} catch (IllegalArgumentException e) {
|
||||
GB.toast("returned uri: " + confUri.toString(), Toast.LENGTH_LONG, GB.ERROR);
|
||||
}
|
||||
((WebView) v).loadUrl("file:///android_asset/app_config/configure.html?" + queryString);
|
||||
} else {
|
||||
//show configuration
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
myWebView.evaluateJavascript("Pebble.evaluate('showConfiguration');", new ValueCallback<String>() {
|
||||
@Override
|
||||
public void onReceiveValue(String s) {
|
||||
LOG.debug("Callback from showConfiguration", s);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
((WebView) v).loadUrl("javascript:Pebble.evaluate('showConfiguration');");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewDetachedFromWindow(View v) {
|
||||
myWebView.removeJavascriptInterface("GBActivity");
|
||||
myWebView.setWillNotDraw(true);
|
||||
FrameLayout fl = (FrameLayout) findViewById(R.id.webview_placeholder);
|
||||
fl.removeAllViews();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@ -60,57 +114,6 @@ public class ExternalPebbleJSActivity extends GBActivity {
|
||||
confUri = incoming.getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
String queryString = "";
|
||||
|
||||
myWebView = WebViewSingleton.getorInitWebView(this, mGBDevice, appUuid);
|
||||
myWebView.addJavascriptInterface(new ActivityJSInterface(this), "GBActivity");
|
||||
|
||||
|
||||
FrameLayout fl = (FrameLayout) findViewById(R.id.webview_placeholder);
|
||||
if (myWebView != null)
|
||||
fl.addView(myWebView);
|
||||
|
||||
//needed to display clay dialogs
|
||||
myWebView.getSettings().setUseWideViewPort(true);
|
||||
myWebView.requestFocus();
|
||||
|
||||
|
||||
if (confUri != null) {
|
||||
//getting back with configuration data
|
||||
try {
|
||||
appUuid = UUID.fromString(confUri.getHost());
|
||||
queryString = confUri.getEncodedQuery();
|
||||
} catch (IllegalArgumentException e) {
|
||||
GB.toast("returned uri: " + confUri.toString(), Toast.LENGTH_LONG, GB.ERROR);
|
||||
}
|
||||
myWebView.loadUrl("file:///android_asset/app_config/configure.html?" + queryString);
|
||||
} else {
|
||||
//show configuration
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
myWebView.evaluateJavascript("Pebble.evaluate('showConfiguration');", new ValueCallback<String>() {
|
||||
@Override
|
||||
public void onReceiveValue(String s) {
|
||||
LOG.debug("Callback from showConfiguration", s);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
myWebView.loadUrl("javascript:Pebble.evaluate('showConfiguration');");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
|
||||
FrameLayout fl = (FrameLayout) findViewById(R.id.webview_placeholder);
|
||||
fl.removeAllViews();
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
|
@ -39,6 +39,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.PebbleProtocol;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.PebbleUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.WebViewSingleton;
|
||||
|
||||
|
||||
public abstract class AbstractAppManagerFragment extends Fragment {
|
||||
@ -323,6 +324,8 @@ public abstract class AbstractAppManagerFragment extends Fragment {
|
||||
|
||||
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
|
||||
popupMenu.show();
|
||||
//TODO: replace with local broadcast on app start
|
||||
WebViewSingleton.getorInitWebView(getActivity(), mGBDevice, selectedApp.getUUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -570,6 +570,7 @@ class PebbleIoThread extends GBDeviceIoThread {
|
||||
case START:
|
||||
LOG.info("got GBDeviceEventAppManagement START event for uuid: " + appMgmt.uuid);
|
||||
WebViewSingleton.getorInitWebView(getContext(), gbDevice, appMgmt.uuid);
|
||||
//TODO: the method call above will not work the first time as we need an activity. Either we find a way to have one here, or replace it with a local broadcast
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1,12 +1,10 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.util;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.MutableContextWrapper;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.webkit.ConsoleMessage;
|
||||
import android.webkit.JavascriptInterface;
|
||||
import android.webkit.WebChromeClient;
|
||||
@ -35,7 +33,7 @@ import java.util.UUID;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
|
||||
public class WebViewSingleton {
|
||||
public class WebViewSingleton extends Activity {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(WebViewSingleton.class);
|
||||
|
||||
@ -46,56 +44,52 @@ public class WebViewSingleton {
|
||||
private WebViewSingleton() {
|
||||
}
|
||||
|
||||
public static WebView getorInitWebView(final Context context, final GBDevice device, final UUID uuid) {
|
||||
final MutableContextWrapper _contextWrapper = new MutableContextWrapper(context);
|
||||
if (contextWrapper != null) {
|
||||
contextWrapper.setBaseContext(context);
|
||||
} else {
|
||||
contextWrapper = _contextWrapper;
|
||||
}
|
||||
|
||||
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (instance == null) {
|
||||
instance = new WebView(_contextWrapper);
|
||||
instance.clearCache(true);
|
||||
instance.setWebViewClient(new GBWebClient());
|
||||
instance.setWebChromeClient(new GBChromeClient());
|
||||
instance.setWebContentsDebuggingEnabled(true);
|
||||
WebSettings webSettings = instance.getSettings();
|
||||
webSettings.setJavaScriptEnabled(true);
|
||||
//needed to access the DOM
|
||||
webSettings.setDomStorageEnabled(true);
|
||||
//needed for localstorage
|
||||
webSettings.setDatabaseEnabled(true);
|
||||
}
|
||||
|
||||
if (jsInterface == null || (jsInterface != null && (!device.equals(jsInterface.device) || !uuid.equals(jsInterface.mUuid)))) {
|
||||
instance.removeJavascriptInterface("GBjs");
|
||||
jsInterface = new JSInterface(device, uuid);
|
||||
instance.addJavascriptInterface(jsInterface, "GBjs");
|
||||
instance.loadUrl("file:///android_asset/app_config/configure.html");
|
||||
} else {
|
||||
LOG.debug("Not reloading the webview " + jsInterface.mUuid.toString());
|
||||
}
|
||||
public static WebView getorInitWebView(Context context, GBDevice device, UUID uuid) {
|
||||
if (context instanceof Activity) {
|
||||
final MutableContextWrapper _contextWrapper = new MutableContextWrapper(context);
|
||||
if (contextWrapper != null) {
|
||||
contextWrapper.setBaseContext(context);
|
||||
} else {
|
||||
contextWrapper = _contextWrapper;
|
||||
}
|
||||
}
|
||||
//here we are sure that contextWrapper is either null or an activity, hence we run on the main thread
|
||||
if (contextWrapper != null) {
|
||||
if (instance == null) {
|
||||
instance = new WebView(contextWrapper);
|
||||
instance.setWillNotDraw(true);
|
||||
instance.clearCache(true);
|
||||
instance.setWebViewClient(new GBWebClient());
|
||||
instance.setWebChromeClient(new GBChromeClient());
|
||||
instance.setWebContentsDebuggingEnabled(true);
|
||||
WebSettings webSettings = instance.getSettings();
|
||||
webSettings.setJavaScriptEnabled(true);
|
||||
//needed to access the DOM
|
||||
webSettings.setDomStorageEnabled(true);
|
||||
//needed for localstorage
|
||||
webSettings.setDatabaseEnabled(true);
|
||||
}
|
||||
});
|
||||
|
||||
if (jsInterface == null || (jsInterface != null && (!device.equals(jsInterface.device) || !uuid.equals(jsInterface.mUuid)))) {
|
||||
instance.removeJavascriptInterface("GBjs");
|
||||
jsInterface = new JSInterface(device, uuid);
|
||||
instance.addJavascriptInterface(jsInterface, "GBjs");
|
||||
instance.loadUrl("file:///android_asset/app_config/configure.html");
|
||||
} else {
|
||||
LOG.debug("Not reloading the webview " + jsInterface.mUuid.toString());
|
||||
}
|
||||
} else {
|
||||
LOG.debug("WEBV: not using the passed context, as it is not an activity");
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
public static void disposeWebView() {
|
||||
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (instance != null) {
|
||||
instance.destroy();
|
||||
instance = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (instance != null) {
|
||||
instance.destroy();
|
||||
instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class GBChromeClient extends WebChromeClient {
|
||||
@ -155,7 +149,7 @@ public class WebViewSingleton {
|
||||
|
||||
@JavascriptInterface
|
||||
public void gbLog(String msg) {
|
||||
Log.d("WEBVIEW", msg);
|
||||
LOG.debug("WEBVIEW", msg);
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
@ -196,7 +190,7 @@ public class WebViewSingleton {
|
||||
}
|
||||
|
||||
}
|
||||
LOG.info(out.toString());
|
||||
LOG.info("WEBV:" + out.toString());
|
||||
GBApplication.deviceService().onAppConfiguration(this.mUuid, out.toString());
|
||||
|
||||
} catch (JSONException e) {
|
||||
|
Loading…
Reference in New Issue
Block a user