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 f2dd3f42b..45e2a8949 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 @@ -2,16 +2,23 @@ package nodomain.freeyourgadget.gadgetbridge.devices.banglejs; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.PREF_DEVICE_INTERNET_ACCESS; +import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.net.Uri; import android.os.Bundle; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.webkit.DownloadListener; import android.webkit.JavascriptInterface; +import android.webkit.PermissionRequest; +import android.webkit.ValueCallback; +import android.webkit.WebChromeClient; +import android.webkit.WebResourceRequest; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; @@ -55,6 +62,8 @@ public class AppsManagementActivity extends AbstractGBActivity { private DeviceCoordinator mCoordinator; /// It seems we can get duplicate broadcasts sometimes - so this helps to avoid that private int deviceRxSeq = -1; + /// When a file chooser has been opened in the WebView, this is what should get called + private ValueCallback fileChooserCallback; public AppsManagementActivity() { } @@ -81,15 +90,12 @@ public class AppsManagementActivity extends AbstractGBActivity { @Override protected void onPause() { super.onPause(); - webView.destroy(); - webView = null; - LocalBroadcastManager.getInstance(this).unregisterReceiver(deviceUpdateReceiver); - finish(); } @Override protected void onResume() { super.onResume(); + if (webView!=null) return; // already set up IntentFilter commandFilter = new IntentFilter(); commandFilter.addAction(GBDevice.ACTION_DEVICE_CHANGED); commandFilter.addAction(BangleJSDeviceSupport.BANGLEJS_COMMAND_RX); @@ -97,6 +103,15 @@ public class AppsManagementActivity extends AbstractGBActivity { initViews(); } + @Override + protected void onDestroy() { + webView.destroy(); + webView = null; + LocalBroadcastManager.getInstance(this).unregisterReceiver(deviceUpdateReceiver); + super.onDestroy(); + finish(); + } + BroadcastReceiver deviceUpdateReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -180,6 +195,79 @@ public class AppsManagementActivity extends AbstractGBActivity { public void onPageFinished(WebView view, String weburl){ //webView.loadUrl("javascript:showToast('WebView in Espruino')"); } + @Override + public boolean shouldOverrideUrlLoading(WebView vw, WebResourceRequest request) { + Intent intent = new Intent(Intent.ACTION_VIEW, request.getUrl()); + vw.getContext().startActivity(intent); + return true; + } + + @Override + public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { + Toast.makeText(AppsManagementActivity.this, "Error:" + description, Toast.LENGTH_SHORT).show(); + view.loadUrl("about:blank"); + } + }); + webView.setWebChromeClient(new WebChromeClient() { + @Override + public void onPermissionRequest(final PermissionRequest request) { + request.grant(request.getResources()); + } + + @Override + public boolean onShowFileChooser(WebView vw, ValueCallback filePathCallback, + FileChooserParams fileChooserParams) { + if (fileChooserCallback != null) { + fileChooserCallback.onReceiveValue(null); + } + fileChooserCallback = filePathCallback; + + Intent selectionIntent = new Intent(Intent.ACTION_GET_CONTENT); + selectionIntent.addCategory(Intent.CATEGORY_OPENABLE); + String[] acceptedTypes = fileChooserParams.getAcceptTypes(); + if ((acceptedTypes!=null) && acceptedTypes.length>0 && acceptedTypes[0].contains("/")) + selectionIntent.setType(acceptedTypes[0]); + else + selectionIntent.setType("*/*"); + + Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER); + chooserIntent.putExtra(Intent.EXTRA_INTENT, selectionIntent); + startActivityForResult(chooserIntent, 0); + + return true; + } + + + }); + webView.setDownloadListener(new DownloadListener() { + public void onDownloadStart(String url, String userAgent, + String contentDisposition, String mimetype, + long contentLength) { + if (url == null) return; + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse(url.replaceFirst("^blob:", ""))); + startActivity(i); + + /*DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); // fails with java.lang.IllegalArgumentException: Can not handle uri:: + request.allowScanningByMediaScanner(); + request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); + request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "download"); + DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); + dm.enqueue(request);*/ + } }); } + + @Override // for file chooser results + protected void onActivityResult(int requestCode, int resultCode, Intent intent) { + super.onActivityResult(requestCode, resultCode, intent); + + if (fileChooserCallback==null) return; + Uri[] results = null; + if (resultCode == Activity.RESULT_OK) + results = new Uri[]{Uri.parse(intent.getDataString())}; + fileChooserCallback.onReceiveValue(results); + fileChooserCallback = null; + } + }